传递元素子项的未记录方法:作为属性而不是显式子项
Undocumented method of passing element children: as attributes instead of explicit children
我在一本书中遇到了一些示例 JSX 代码,这让我感到惊讶 - 它包含一个单一(非封闭)形式的锚标记。我已经简化了代码:
function CustomAnchor(props) {
return <a {...props}/>;
};
ReactDOM.render(
<CustomAnchor href="http://reactjs.com">A link</CustomAnchor>,
document.getElementById('container')
);
该代码有效,但我无法找到任何描述这种在 JSX 中描述锚标记的方式的文档。我预计必须使用开始和结束 A 标签,包含 props.children - 即 - 像这样的东西:
return <a {...props}>{props.children}</a>
实际上,后一种形式在同一本书的较早部分是如何完成的,并且没有对新的更简洁的形式进行解释。 FWIW,这本书是 "React Up & Running",作者是 Stoyan Stefanov。在我考虑提交为本书添加解释的建议之前,我会很感激这里的一些帮助。
JSX 和 React.createElement()
如果你查看 Babel Compiler,你会看到这个 JSX:
function CustomAnchor() {
return <a {...props} />;
}
编译成:
function CustomAnchor() {
return React.createElement("a", props);
}
createElement()
函数具有以下语法,根据 official documentation:
createElement():
React.createElement(
type,
[props],
[...children]
)
所以你的观察是有道理的!有人会认为,既然省略了第三个参数,那么就不应该有任何 children
.
说明
所以这是怎么回事?需要仔细查看源代码才能了解发生了什么:
在react库第170行的ReactElement.js
中:
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];
}
}
}
对于 config
对象中的每个值(即 第二个函数参数 !),我们将其传递给 props
和 propName
钥匙。但是,请记住,您在 <a>
元素.
中解构了 props
换句话说,这个:
<a {...props} />
等于:
<a href="http://reactjs.com" children="A link" />
这意味着 props
对象同时获得 href
和 children
属性,这就是为什么您会得到观察到的结果。
总结
总而言之,这:
<Foo children="Bar" />
等于:
<Foo>Bar</Foo>
意见:
也就是说,我宁愿看到作者使用您建议的语法,而不是 he/she 的做法。人们希望教育 material 更加清晰和准确。
我在一本书中遇到了一些示例 JSX 代码,这让我感到惊讶 - 它包含一个单一(非封闭)形式的锚标记。我已经简化了代码:
function CustomAnchor(props) {
return <a {...props}/>;
};
ReactDOM.render(
<CustomAnchor href="http://reactjs.com">A link</CustomAnchor>,
document.getElementById('container')
);
该代码有效,但我无法找到任何描述这种在 JSX 中描述锚标记的方式的文档。我预计必须使用开始和结束 A 标签,包含 props.children - 即 - 像这样的东西:
return <a {...props}>{props.children}</a>
实际上,后一种形式在同一本书的较早部分是如何完成的,并且没有对新的更简洁的形式进行解释。 FWIW,这本书是 "React Up & Running",作者是 Stoyan Stefanov。在我考虑提交为本书添加解释的建议之前,我会很感激这里的一些帮助。
JSX 和 React.createElement()
如果你查看 Babel Compiler,你会看到这个 JSX:
function CustomAnchor() {
return <a {...props} />;
}
编译成:
function CustomAnchor() {
return React.createElement("a", props);
}
createElement()
函数具有以下语法,根据 official documentation:
createElement():
React.createElement( type, [props], [...children] )
所以你的观察是有道理的!有人会认为,既然省略了第三个参数,那么就不应该有任何 children
.
说明
所以这是怎么回事?需要仔细查看源代码才能了解发生了什么:
在react库第170行的ReactElement.js
中:
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];
}
}
}
对于 config
对象中的每个值(即 第二个函数参数 !),我们将其传递给 props
和 propName
钥匙。但是,请记住,您在 <a>
元素.
props
换句话说,这个:
<a {...props} />
等于:
<a href="http://reactjs.com" children="A link" />
这意味着 props
对象同时获得 href
和 children
属性,这就是为什么您会得到观察到的结果。
总结
总而言之,这:
<Foo children="Bar" />
等于:
<Foo>Bar</Foo>
意见:
也就是说,我宁愿看到作者使用您建议的语法,而不是 he/she 的做法。人们希望教育 material 更加清晰和准确。