传递元素子元素的未记录方法:作为属性而不是显式子元素

时间:2017-05-18 08:21:27

标签: javascript reactjs ecmascript-6 jsx

我在一本书中遇到了一些示例JSX代码,这让我感到惊讶 - 它包含单个(非封闭)形式的锚标记。我简化了代码:

function CustomAnchor(props) {
    return <a {...props}/>;
};

ReactDOM.render(
  <CustomAnchor href="http://reactjs.com">A link</CustomAnchor>,
  document.getElementById('container')
);

代码有效,但我无法找到任何描述这种描述JSX中锚标记的方法的文档。我预计必须使用一个开口和放大器关闭一个标签,包括props.children - 即 - 像这样:

return <a {...props}>{props.children}</a>

后一种形式实际上是如何在同一本书中稍早完成的,并且没有对新的更精简的形式给出解释。 FWIW,这本书是由Stoyan Stefanov撰写的“React Up&amp; Running”。在我考虑提交一个建议来为本书添加解释之前,我会感激一些帮助。

Codepen:https://codepen.io/anon/pen/EmeOxW?editors=0010

1 个答案:

答案 0 :(得分:3)

JSX和React.createElement()

如果你看一下Babel Compiler,你会看到这个JSX:

function CustomAnchor() {
  return <a {...props} />;
}

编译成:

function CustomAnchor() {
  return React.createElement("a", props);
}

根据official documentation

createElement()函数具有以下语法
  

<强>的createElement():

React.createElement(
  type,
  [props],
  [...children]
)

所以你的观察是有道理的!有人会认为,由于省略了第3个参数,因此不应该是children

解释

那是怎么回事?人们需要仔细研究源代码才能理解发生了什么:

在反应库的第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。但是,请记住,您已在props元素中解构<a>

换句话说,这个:

<a {...props} />

等于:

<a href="http://reactjs.com" children="A link" />

这意味着props对象同时获得hrefchildren属性,这就是您获得观察结果的原因。

摘要

总而言之,这个:

<Foo children="Bar" />

等于:

<Foo>Bar</Foo>

<强>意见:

话虽这么说,我宁愿看到作者使用你建议的语法,而不是他/她做的方式。人们期望教育材料更加清晰和准确。