在React官網中,可以看到對生命周期的描述
這里有一個疑問是,在嵌套組件中,是父組件先構建,還是子組件先構建?是子組件先更新,還是父組件先更新
解決這個問題,可以從嵌套單個元素入手。下面是一個只有DOM元素的組件 Parent
1
2
3
4
5
|
function Parent(){ return ( <div>child</div> ) } |
對于上面的元素,React會調用React.createElement創建一個對象,這就是子元素的構建階段(這里使用的是babeljs.io/)
1
|
React.createElement( "div" , null , "child" ) |
構建之后就是渲染、更新
接著看下嵌套組件
1
2
3
4
5
6
7
8
|
function Child() { return <div>child</div> } function Parent(){ return ( <Child>parent child</Child> ) } |
React會調用React.createElement,并傳入以下參數
1
2
3
4
5
6
7
|
function Child() { return React.createElement( "div" , null , "child" ); } function Parent() { return React.createElement(Child, null , "parent child" ); } |
這里我們看出父子組件的構建過程,首先對當前組件進行構建,接著進入到組件中,繼續構建,遵循的原則是從上到下
接著看看傳入多個組件
1
2
3
4
5
6
7
8
9
10
11
|
function Child() { return <div>child組件</div> } function Parent(){ return ( <div> <div>div元素</div> <Child /> </div> ) } |
在React.createElement會傳入以下參數
1
2
|
React.createElement( "div" , null , React.createElement( "div" , null , "div\u5143\u7D20" ),React.createElement(Child, null )) React.createElement( "div" , null , "child\u7EC4\u4EF6" ) |
可以進一步明確,子組件的構建和父組件是分離的,并且是在父組件構建之后創建的。所以父子組件的構建順序是父組件constructor,render子組件constructor,render
當子組件render完成后,會調用componentDidMount
構建總結
在多組件情況下,首先父元素constructor,進行初始化和開始掛載,接著調用render
對于DOM元素,會立即創建,對于React組件,會在之后進入到組件中,重復之前的constructor,構建,render,直到最后一個子元素
當最后一個子組件render完成后,會調用componentDidMount。也就是元素已經掛載完成。之后會層層向上,依次調用componentDidMount
偏離一點點主題
下面的代碼可以輔助理解上面的內容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
// RenderChild的作用是,當接收到值時,渲染children,沒有值時,渲染其他元素 function RenderChild(props){ return ( props.a ? props.children : <div>aaaa</div> ) } 寫法一(直接渲染DOM元素): function Parent(){ let a = undefined; setTimeout(() => { a = { b: 1 }; }); return ( <RenderChild val={a}> <div>{a.b}</div> </RenderChild> ) } 寫法二(渲染組件): function Child(props) { return <div>{props.a.b}</div> } function Parent(){ const a = undefined; setTimeout(() => { a = { b: 1 }; }); return ( <RenderChild val={a}> <Child childVal={a} /> </RenderChild> ) } |
在上面兩種寫法中,第一種一定會報錯
因為第一種的構建參數是
1
2
|
React.createElement(RenderChild, { val: a },React.createElement( "div" , null , a.b)) 此時a還是undefined |
第二種構建參數是
1
2
3
4
5
6
7
8
9
10
|
function RenderChild(props) { return props.val ? props.children : React.createElement( "div" , null , "aaaa" ); } function Child(props) { return React.createElement( "div" , null , props.value.b); } React.createElement(RenderChild, { val: a }, React.createElement(Child, { value: a })); |
因為Child的構建是在RenderChild之后的,所以即使在Child中使用到了不存在的值,也不會報錯
最后總結
1. React組件的構建和開始掛載是從根元素到子元素的,因此數據流是從上到下的,掛載完成和狀態的更新是從子元素到根元素,此時可以將最新狀態傳給根元素
2. 組件和DOM元素的一個區別是,DOM元素會在當前位置創建,而React組件的構建渲染具有層級順序
以上就是React嵌套組件的構建順序的詳細內容,更多關于React嵌套組件的構建的資料請關注服務器之家其它相關文章!
原文鏈接:https://juejin.cn/post/6949372925732454437