React 函数式组件直接调用 vs jsx - children 在哪里?

React function style component direct invocation vs jsx - where is the children?

我想了解自定义组件 jsx 样式的 children 在哪里?

const appDom = document.getElementById('app')

const Hey = () => <div><i>HEY</i><b>you</b></div>
const Hello = () => <div><h1>Hello</h1></div>

console.log('ola', Hey()['props'])
console.log('hola', <Hey />['props']) // Where is children?


ReactDOM.render(<div>{Hey()}<br/><Hey/></div>, appDom)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

要找到问题的答案,首先,我们需要了解当 JSX 转换为正常时会发生什么 JavaScript。编译器只需使用 React.createElement 方法重写整个 JSX 标记树。

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

在此转换为React.createElement,

  • JSX 标签将作为类型传递,
  • 标签的所有属性将被组合成一个 JavaScript object 并作为 props and
  • 传递
  • JSX 标签之间的内容在递归应用 React.createElement 方法后将作为 children 传递。

这个 React.createElement returns 一个 React Element 这只是一个普通的 object.

所以你的 Hey 组件将像下面的正常 JavaScript 形式。

const Hey = () => React.createElement(
  "div",
  null,
  React.createElement(
    "i",
    null,
    "HEY"
  ),
  React.createElement(
    "b",
    null,
    "you"
  )
);

你的控制台日志行将是这样的。

console.log('ola', Hey()['props']);
console.log('hola', React.createElement(Hey, null)['props']);

现在,如果您仔细查看这些日志行,第一行打印的是 div 反应元素的 props,它有两个 children;我反应元素和 b 反应元素。但是第二行打印了 Hey react 元素的 props,它没有任何 children。所以它不打印 children 因为它没有任何 children。基本上,Hey()<Hey/> 不是一回事,即使它们呈现的内容没有区别。

为了更好地理解它,让我们尝试另一个控制台日志,如下所示,

console.log('hola', <Hey>abc</Hey>['props'])

转换为

console.log('hola', React.createElement(Hey, null, 'abc' )['props']);

这仍然会打印 Hey react 元素的 props,但它会有 children 属性,即 'abc' 字符串。

希望这能回答您的问题。