I have encountered some example JSX code in a book which took me by surprise - it contains an anchor tag in the single (non-closed) form. I have simplified the code:
function CustomAnchor(props) {
return <a {...props}/>;
};
ReactDOM.render(
<CustomAnchor href="http://reactjs.com">A link</CustomAnchor>,
document.getElementById('container')
);
The code works, but I haven't been able to find any documentation that describes this way of describing the anchor tag in JSX. I expected to have to use an opening & closing A tag, enclosing props.children - i.e - something like this:
return <a {...props}>{props.children}</a>
The latter form is in fact how it was done a bit earlier in this same book, and no explanation has been given on the new more condensed form. FWIW, the book is "React Up & Running", by Stoyan Stefanov. I'd appreciate some help here before I consider submitting a suggestion to add an explanation to the book.
Codepen: https://codepen.io/anon/pen/EmeOxW?editors=0010
React.createElement()
If you look at the Babel Compiler, you'll see that this JSX:
function CustomAnchor() {
return <a {...props} />;
}
compiles into:
function CustomAnchor() {
return React.createElement("a", props);
}
The createElement()
function has the following syntax, as per the official documentation:
createElement():
React.createElement( type, [props], [...children] )
So your observation makes sense! One would think that since the 3rd parameter is omitted then there shouldn't be any children
.
So what's going on? One would need to take a closer look at the source code to understand what's going on:
In ReactElement.js
on line 170 in the react library:
ReactElement.createElement = function (type, config, children) {
var propName;
// Reserved names are extracted
var props = {};
........
for (propName in config) {
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
props[propName] = config[propName];
}
}
}
For each value in the config
object (i.e the 2nd function argument!), we pass it to props
with the propName
key. However, remember that you deconstructed props
in your <a>
element.
In other words, this:
<a {...props} />
is equal to:
<a href="http://reactjs.com" children="A link" />
This means that props
object gets both an href
and a children
property, which is why you get the result you observed.
So in summary, this:
<Foo children="Bar" />
is equal to:
<Foo>Bar</Foo>
Opinion:
That being said, I would rather see the author use your suggested syntax and not the way he/she did it. One would expect educational material to be more clear and precise.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With