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' 字符串。
希望这能回答您的问题。
我想了解自定义组件 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' 字符串。
希望这能回答您的问题。