I want to loop through a props screenshots but it's not working for me! I used to do it in other components and it was working. I'm losing my mind :(
please find below my code:
{screenshots && <h2>Hello</h2>}
this works and rendered perfectly.
but when I do a loop like
{screenshots && screenshots.length && screenshots.map(screenshot => {
<div className="container img--container" key={screenshot.id}>
<SVG
className="icon remove--icon"
src={removeCircle}
/>
<img src={screenshot.image} title={"screenshot"} className="p-absolute"/>
</div>
})}
what's inside the loop doesn't get rendered!
and the console doesn't show any error.
please any help?
Missing return!! You can use "()" to return immediate.
{screenshots && screenshots.length && screenshots.map(screenshot => (
<div className="container img--container" key={screenshot.id}>
<SVG
className="icon remove--icon"
src={removeCircle}
/>
<img src={screenshot.image} title={"screenshot"} className="p-absolute"/>
</div>
))}
When using map, you have to be careful what to put after the =>.
If you have to process elements of the array when mapping, do this:
array.map(a => {
// Javascript here
return(
<div>JSX here!</div>
);
});
If you just have to render JSX, do this:
array.map(a => (
<div>JSX here!</div>
));
Since => () is implicitly returning the stuff between ().
In arrow functions curly brackets are used for closures. So it will wrap your function.
If you use arrow function with curly brackets, you have to use return. Like this:
screenshots.map(screenshot => {
console.log('I can do whatever I like here...');
return 'but I have to return something!'
});
Arrow function without curly brackets automatically returns your statement and it has to be used only with one statement.
screenshots.map(screenshot =>
'It returns this string without using word `return`!'
);
Your code should look like this (with curly brackets and return):
{screenshots && screenshots.length && screenshots.map(screenshot => {
console.log('Wow! I am in arrow function! I have to return something.');
return
<div className="container img--container" key={screenshot.id}>
<SVG className="icon remove--icon" src={removeCircle}/>
<img src={screenshot.image} title={"screenshot"} className="p-absolute"/>
</div>
})}
or you can just delete curly brackets like this:
{screenshots && screenshots.length && screenshots.map(screenshot =>
<div className="container img--container" key={screenshot.id}>
<SVG className="icon remove--icon" src={removeCircle}/>
<img src={screenshot.image} title={"screenshot"} className="p-absolute"/>
</div>
)}
You can read more about arrow functions at w3schools.
Related
I am getting an error of in the below
Line 56:11: Expected an assignment or function call and instead saw an expression no-unused-expressions
<div className="posts_container">
{
(userPosts.length) ?
(
<div>
{
userPosts.map((post,idx)=>{
<div className="smallPost">
<img className='smallPost_pic' alt='post_img' src={post.imageurl}/>
</div>
})
}
</div>
)
:
(
<h1> No posts Yet </h1>
)
}
</div>
please help me to solve this.
Thanks in advance.
The function that's passed to .map isn't returning anything.
So either add return:
userPosts.map((post,idx) => {
return (
<div className="smallPost">
<img className='smallPost_pic' alt='post_img' src={post.imageurl}/>
</div>
)
})
or replace the curly braces with parentheses:
userPosts.map((post,idx) => (
<div className="smallPost">
<img className='smallPost_pic' alt='post_img' src={post.imageurl}/>
</div>
)
)
As a sidenote, remember to add a key to the div that is returned from the .map function. More about that in React's docs: Lists and Keys
I have following code which doesnt show any list as expected.
I am confused why its not working , whats missing .
return (
<div>
List
<ul>
{events.map((event,index)=>{
<li key={index}>Name:{event.name}</li>
})
}
</ul>
</div>
);
Above code is a return block of function component I tried replacing the with many other tags but it just doesnt return anything expect the text outside the map function.
Please help.
You have a typo - you're using { } braces there, in which case you'd need a return too. Failing to have a return in a curly-braced function equals an implicit return undefined;.
return (
<div>
List
<ul>
{events.map((event, index) => {
return <li key={index}>Name:{event.name}</li>;
})}
</ul>
</div>
);
Or, more simply, use regular parentheses to make the return implicit (see Concise body here):
return (
<div>
List
<ul>
{events.map((event, index) => (
<li key={index}>Name:{event.name}</li>
))}
</ul>
</div>
);
I am trying to split a given text at each \n in order to put them on individual lines.
The problem is, in React, I am using the following code:
const details = property.details !== undefined
? property.details.split("\n").map((item, i) => {
return <p key={i}>{item}</p>;
})
: "";
but there is no splitting made whatsoever. The returned array is simply the whole string. I tried the same string in the console of the browser and it works there.
Also, the typeof property.details is string.
What am I missing?
My render function for this component is:
render() {
const property = this.state.property;
const details =
property.details !== undefined
? property.details.split(/\r?\n/).map((item, i) => {
return <p key={i}>{item}</p>;
})
: "";
return (
<Fragment>
{this.state.isLoading ? (
<div className="sweet-loading" style={{ marginTop: "120px" }}>
<BarLoader
sizeUnit={"px"}
css={override}
size={200}
color={"#123abc"}
loading={this.state.isLoading}
/>
</div>
) : (
<div className="container p-4" style={{ marginTop: "4rem" }}>
<div className="row align-items-center">
<div className="row display-inline p-3">
<h3>{property.title}</h3>
<h5 className="fontw-300">{property.zone}</h5>
<h1 className="mt-5 price-font-presentation">
{property.sale_type} -{" "}
<strong>{property.price.toLocaleString()} EUR</strong>
</h1>
</div>
<Carousel>
{property.images.map(image => (
<img key={image.id} src={image.image} />
))}
</Carousel>
<div className="row p-3">
<h3 className="border-bottom">Detalii</h3>
{details}
</div>
</div>
</div>
)}
</Fragment>
);
}
Maybe I should mention that the information is taken with a django_rest api. Maybe there is a problem with returning \n in a string from there.
It might happen because client OS uses different symbols for new lines. Try this, it's multi-platform:
const details = property.details !== undefined
? property.details.split(/\r?\n/)
: [];
EDIT:
typeof property.details is string because it's string. calling split on property.details returns array, but string remains to be string.
From your updated code sample I can see that you are basically rendering details, which results in array transforming to string back again but without line seperators.
Maybe you have to map it to paragraphs for example:
<h3 className="border-bottom">Detalii</h3>
{details.map(detail => <p>{detail}</p>)}
Also, try white-space: pre; css property as alternative
Have you tried this version:
const details = property.details !== undefined
? property.details.split('\r\n').map((item, i) =>
<p key={i}>{item}</p>;
)
: '';
(It's the extra \r)
I have the following code:
return (
</React.Fragment>
...
<div className="col-md-6">
{firstHalfy1.map(month => (<Field key={month.id} {...month}/>))}
</div>
</React.Fragment>
);
I want to add another tag/functional component after the component, but the syntax doesn't seem to work. Ideally I want something like:
{firstHalfy1.map(month => (<Field/><Component2/>))}
is this syntax possible as I am trying to render a button (Component2) after every input (Field)?
Thanks!
{firstHalfy1.map(month => (<div key={your key}><Field/><Component2/></div>))}
You need a wrapper for those components, such as a div or React.Fragment. Plus you need a key for each month.
You can use from fragment like this:
<>...
This empty tag is also fragment
{firstHalfy1.map(month => (
<React.Fragment key={month.id}>
<Field {...month}/>
<Component2/>
</React.Fragment>
))}
Can you use a if statement in JSX like this?
var chartGraphContent =
<div className={"chartContent"}>
if(this.state.modalityGraph['nca'] > 0){
<div className={"chart-container"}>
<Chart
chartType="ColumnChart"
data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
options={chartOptions}
graph_id="modalitiesChart"
width="100%"
height="250px"
/>
</div>
}
</div>;
Something like above? Is it possible to have JSX based on a condition?
Use conditional rendering, and since you have no else-case, you can use && instead of a ternary operator for brevity:
It works because in JavaScript, true && expression always evaluates to expression, and false && expression always evaluates to false.
Therefore, if the condition is true, the element right after && will appear in the output. If it is false, React will ignore and skip it.
Thus:
<div className={"chartContent"}>
{this.state.modalityGraph['nca'] > 0 &&
<div className={"chart-container"}>
<Chart
chartType="ColumnChart"
data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
options={chartOptions}
graph_id="modalitiesChart"
width="100%"
height="250px"
/>
</div>
}
</div>
This will only render JSX if a condition is true. If it is false, React won't render anything. Remember, you have to wrap inline JavaScript expressions in JSX with { … }, you can't just have it inside JSX.
Using if/else statements directly in JSX will cause it to be rendered literally as text, which isn't desired. You also can't use them in inline JavaScript expressions because if statements are not expressions, so this won't work:
{
if(x) y
}
As per DOC:
if-else statements don't work inside JSX. This is because JSX is just
syntactic sugar for function calls and object construction.
We can't use if-else statement or any other statement directly inside JSX, only expressions are allowed.
Expressions inside JSX:
Wou can embed any JavaScript expression in JSX by wrapping it in curly
braces.
To put any expression we need to use {}, so instead of if use && operator or ternary operator for conditional rendering.
By using ternary operator:
var chartGraphContent =
<div className={"chartContent"}>
{
this.state.modalityGraph['nca'] > 0 ?
<div className={"chart-container"}>
<Chart
chartType="ColumnChart"
data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
options={chartOptions}
graph_id="modalitiesChart"
width="100%"
height="250px"
/>
</div>
:null
}
</div>;
By using && operator:
var chartGraphContent =
<div className={"chartContent"}>
{
this.state.modalityGraph['nca'] > 0 &&
<div className={"chart-container"}>
<Chart
chartType="ColumnChart"
data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
options={chartOptions}
graph_id="modalitiesChart"
width="100%"
height="250px"
/>
</div>
}
</div>;
Better to use with ternary Operator, By doing so you can also add else block to your code.
Try this:
var chartGraphContent =
<div className={"chartContent"}>
{this.state.modalityGraph['nca'] > 0 ?
<div className={"chart-container"}>
<Chart
chartType="ColumnChart"
data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
options={chartOptions}
graph_id="modalitiesChart"
width="100%"
height="250px"
/>
</div>
: "<span>Else Block</span>"
}
</div>;
Update (Another method)
and in case for more complex and large condition you can call inline functions too to return your template , in this way you can avoid your code to become messy. here is an example.
var ifBlockCode = function ifBlockCode(){
return (
<div className={"chart-container"}>
<Chart
chartType="ColumnChart"
data = { this.state.modalityGraph?this.state.modalityGraph.chartData['units']:emptyDataRows }
options={chartOptions}
graph_id="modalitiesChart"
width="100%"
height="250px"
/>
</div>
)
}
var elseBlockCode = function elseBlockCode(){
return (
<span>Else Block</span>
)
}
var chartGraphContent =
<div className={"chartContent"}>
{this.state.modalityGraph['nca'] > 0 ?
{this.ifBlockCode} : {this.elseBlockCode}
}
</div>;