gpt4 book ai didi

javascript - 为什么 ReactDOM.render 需要在创建虚拟 DOM 后再次调用函数或类组件?

转载 作者:行者123 更新时间:2023-12-04 17:10:34 31 4
gpt4 key购买 nike

我知道 React 以递归方式使用 React.createElement() 来创建虚拟 DOM。

例如:如果我们有一个具有此标记的 App 组件:

<div className="app">
<span>3<span/>
<Br />
content 1
<div/>

变成:

 ReactDOM.render(React.createElement(App, {}))

这会返回这个对象:

{
type: App,
props: {},
}

这将调用另一个 React.createElement

React.createElement('div', { className: 'app"}, //children) 

这将返回这个对象:

{
type: 'div',
props: {
className: 'app',
children: [
React.createElement('span', {}, 3),
React.createElement('br'),
'content 1'
]
}
}

这个过程一直持续到整个虚拟 DOM 被创建。

现在当 ReactDOM.render() 工作时,它使用这些对象在浏览器中创建真实的 DOM 节点。

我正在阅读 this article这很好地解释了这个过程,但这里有些东西让我感到困惑,

If a type attribute holds a string with a tag name—create a tag with all attributes listed under props.

If we have a function or a class under type—call it and repeat theprocess recursively on a result.

If there are any children under props—repeat the process for eachchild one by one and place results inside the parent’s DOM node.

我的问题是:

If we have a function or a class under type—call it and repeat theprocess recursively on a result

为什么 ReactDOM.render() 不直接使用 React.createElement() 创建的对象,而是再次调用函数组件来获取底层 DOM 元素?我错过了什么吗?如果 React.createElement() 返回有关组件的所有详细信息,为什么我们需要再次这样做??

最佳答案

我认为部分问题在于您提供的前提中的信息与 React.createElement 的实际返回值相比过于简单。让我们看一个真实的例子,父组件使用状态钩子(Hook)的实例,子组件使用它的 props(没有任何 JSX,就像你的帖子):

<div id="root"></div>

<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>

<script type="module">

const {createElement, useState} = React;

function Count (props) {
return createElement('span', null, props.value);
}

function App () {
const [count, setCount] = useState(0);

const reactElement = createElement(
'div',
null,
createElement(
'div',
null,
createElement('span', null, 'Count:'),
' ',
createElement(Count, {value: count}),
),
createElement('button', {onClick: () => setCount(n => n + 1)}, 'Increment'),
);

console.log(reactElement);
return reactElement;
}

ReactDOM.render(createElement(App), document.getElementById('root'));

</script>

在运行上面的示例时查看浏览器中的 JS 控制台,并检查记录的 react 元素上的 props 对象。找到 props 上的 children 属性,并检查数组中的每个对象。然后递归地对数组中的每个对象重复这个过程,一直向下到节点层次结构。

研究值后,单击示例中的“增量”按钮,并在重新渲染后再次(递归地)检查结构。你会发现结构上的差异,其中一些差异是由传递给函数组件 Count 的 props 对象的变化引起的。这个简单的例子说明了为什么有必要在每次渲染中调用每个功能组件的一个原因,但是 React 创建和使用的内部状态值更多取决于在每次渲染时对这些函数的确定性调用。

关于javascript - 为什么 ReactDOM.render 需要在创建虚拟 DOM 后再次调用函数或类组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69533027/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com