Reputation: 2784
Everything works fine, but I have this warning Expected to return a value at the end of arrow function array-callback-return
. I tried using forEach
instead of map
, but then <CommentItem />
doesn't even show. How do I fix this?
return this.props.comments.map((comment) => {
if (comment.hasComments === true) {
return (
<div key={comment.id}>
<CommentItem className="MainComment"/>
{this.props.comments.map(commentReply => {
if (commentReply.replyTo === comment.id) {
return (
<CommentItem className="SubComment"/>
) // return
} // if-statement
}) // map-function
} // map-function __begin
</div> // comment.id
) // return
Upvotes: 121
Views: 241137
Reputation: 17
You can use the for loop like so:
for(let i = 0 ; i < comments.length; i++){
if(comments[i].hasComments === true){
return (
<div key={comments[i].id}>
//content Here
</div> // comment.id
)
}
}
Upvotes: 0
Reputation: 7654
The warning indicates that you're not returning something at the end of your map arrow function in every case.
A better approach to what you're trying to accomplish is first using a .filter
and then a .map
, like this:
this.props.comments
.filter(commentReply => commentReply.replyTo === comment.id)
.map((commentReply, idx) => <CommentItem key={idx} className="SubComment"/>);
Upvotes: 122
Reputation: 2348
The easiest way only if you don't need return something it'ts just return null
Upvotes: 37
Reputation: 683
class Blog extends Component{
render(){
const posts1 = this.props.posts;
//console.log(posts)
const sidebar = (
<ul>
{posts1.map((post) => {
//Must use return to avoid this error.
return(
<li key={post.id}>
{post.title} - {post.content}
</li>
)
})
}
</ul>
);
const maincontent = this.props.posts.map((post) => {
return(
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
)
})
return(
<div>{sidebar}<hr/>{maincontent}</div>
);
}
}
const posts = [
{id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
{id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
<Blog posts={posts} />,
document.getElementById('root')
);
Upvotes: -2
Reputation: 340
The most upvoted answer, from Kris Selbekk, it is totally right. It is important to highlight though that it takes a functional approach, you will be looping through the this.props.comments
array twice, the second time(looping) it will most probable skip a few elements that where filtered, but in case no comment
was filtered you will loop through the whole array twice. If performance is not a concern in you project that is totally fine. In case performance is important a guard clause
would be more appropriated as you would loop the array only once:
return this.props.comments.map((comment) => {
if (!comment.hasComments) return null;
return (
<div key={comment.id}>
<CommentItem className="MainComment"/>
{this.props.comments.map(commentReply => {
if (commentReply.replyTo !== comment.id) return null;
return <CommentItem className="SubComment"/>
})}
</div>
)
}
The main reason I'm pointing this out is because as a Junior Developer I did a lot of those mistakes(like looping the same array multiple times), so I thought i was worth mention it here.
PS: I would refactor your react component even more, as I'm not in favour of heavy logic in the html part
of a JSX
, but that is out of the topic of this question.
Upvotes: 6
Reputation: 30810
A map()
creates an array, so a return
is expected for all code paths (if/elses).
If you don't want an array or to return data, use forEach
instead.
Upvotes: 210
Reputation: 59551
The problem seems to be that you are not returning something in the event that your first if
-case is false.
The error you are getting states that your arrow function (comment) => {
doesn't have a return statement. While it does for when your if
-case is true, it does not return anything for when it's false.
return this.props.comments.map((comment) => {
if (comment.hasComments === true) {
return (
<div key={comment.id}>
<CommentItem className="MainComment" />
{this.props.comments.map(commentReply => {
if (commentReply.replyTo === comment.id) {
return (
<CommentItem className="SubComment"/>
)
}
})
}
</div>
)
} else {
//return something here.
}
});
edit you should take a look at Kris' answer for how to better implement what you are trying to do.
Upvotes: 11