React包装组件元素树构建逻辑及props.children位置疑问
React组件元素树构建与props.children的时机/位置解析
示例组件结构
const App = () => { return <div><Header /><Main/><Footer/></div> } const Header = () => { return <>Header</>; } const Main= () => { return <>Main</>; } const Footer= () => { return <>Footer</>; }
初始React元素结构
当使用<App><div>A</div></App>时,React生成的初始元素结构如下:
{ $$typeof: Symbol(react.element), type: ƒ App(), key: null, ref: null, props: { children: { $$typeof: Symbol(react.element), type: "div", key: null, ref: null, props: { children: "A" }, ... } }, ... }
问题解答
1. React调用App组件时元素树的构建步骤
当你渲染<App><div>A</div></App>时,React会按以下逻辑构建元素树:
- 第一步,React先解析顶层JSX,生成App组件的元素描述对象(也就是上面贴出的包含
type: ƒ App()的对象),此时<div>A</div>已经被解析为React元素,存在props.children中。 - 接着React调用
App组件函数,执行内部代码:- 解析
App返回的JSX,生成一个<div>元素,以及<Header />、<Main />、<Footer />各自的组件元素描述对象(这三个组件此时还未执行,只是先记录它们的类型与属性)。 - 这个
<div>元素会作为父节点,它的子元素列表就是Header、Main、Footer三个组件元素。
- 解析
- 最后React会逐层处理这个元素树:
- 先后调用
Header、Main、Footer组件,拿到它们各自返回的内容(比如Header返回带文本的Fragment)。 - 将这些内容对应的DOM节点挂载到父节点下,最终形成完整的DOM树结构。
- 先后调用
2. props.children的创建时机与位置
- 创建时机:
<div>A</div>对应的React元素,是在React解析顶层<App><div>A</div></App>这段JSX时就生成的,早于App组件函数的执行。也就是说,当App开始执行时,props.children已经是一个现成的React元素对象。 - 位置逻辑:
- 像你原来的
App代码那样**未使用props.children**的话,这个<div>A</div>会被直接忽略,最终渲染的页面只有Header、Main、Footer的内容,看不到A。 - 若修改
App组件,把props.children加入返回的JSX中,比如:
那么const App = ({ children }) => { return <div><Header /><Main/>{children}<Footer/></div> }App执行时,props.children会被插入到返回的<div>的子元素列表里,位置在Main之后、Footer之前。后续React处理元素树时,会把<div>A</div>对应的DOM节点挂载到这个位置。
- 像你原来的
内容的提问来源于stack exchange,提问作者d.s
相关产品推荐
相关产品推荐

