Reputation: 217
I'm looking off of the reactjs tutorial on how to build a comment box with react. I get that we are mapping over data, but I cant understand this syntax and part of the code. Would be really helpful if you could explain exactly what is going on here. Specifically, why is props author={comment.author} within the Comment element tag itself and {comment.text} is not.
<Comment author={comment.author}>
{comment.text}
</Comment>
Context:
var data = [
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
];
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
);
});
Upvotes: 2
Views: 1061
Reputation: 33691
Firstly, we should understand, how Comment
is defined. From the ReactJS tutorial:
var Comment = React.createClass({
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
{this.props.children}
</div>
);
}
});
The call to React.createClass
defines new component, which could be rendered in the following way:
<Comment author="Pete Hunt">This is one comment</Comment>
<!-- Will be transformed into -->
<div className="comment">
<h2 className="commentAuthor">
Pete Hunt
</h2>
This is one comment
</div>
As you can see, {this.props.author}
has been replaced with Pete Hunt
, defined as author
property of Comment
component, and {this.pros.children}
- with Comment
's content (just This is one comment
in this case).
Now we could move to CommentList
declaration. Your commentNodes
function is a part of this component, so, I'll show full definition:
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
Here you can see render
function, defined in terms of commentNotes
(<div className="commentList"> {commentNodes} </div>
). So, what does commentNodes
do?
It transforms each comment
object into Comment
component. Suppose, we have this.props.data
defined as:
var data = [
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
];
Thus, calling commentNodes
will create the following components:
<Comment author="Pete Hunt">This is one comment</Comment>
<Comment author="Jordan Walke">This is *another* comment</Comment>
That will be rendered as:
<div className="comment">
<h2 className="commentAuthor">
Pete Hunt
</h2>
This is one comment
</div>
<div className="comment">
<h2 className="commentAuthor">
Jordan Walke
</h2>
This is *another* comment
</div>
UPD
Specifically, why is props author={comment.author} within the Comment element tag itself and {comment.text} is not.
This is pretty simple - by design. You could rewrite Comment
component in the following way:
var Comment = React.createClass({
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
{this.props.content}
</div>
);
}
});
And rewrite CommentList
as:
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author} content={comment.text} />
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
Note also, passing comment text as {this.props.children}
allows you to create Comment
with nested elements, not only with text.
Upvotes: 3