React嵌套組件的構建順序

在React官網中,可以看到對生命周期的描述

這裡有一個疑問是,在嵌套組件中,是父組件先構建,還是子組件先構建?是子組件先更新,還是父組件先更新

解決這個問題,可以從嵌套單個元素入手。下面是一個隻有DOM元素的組件 Parent

function Parent(){
  return (
    <div>child</div>
  )
}

對於上面的元素,React會調用React.createElement創建一個對象,這就是子元素的構建階段(這裡使用的是babeljs.io/)

React.createElement("div", null, "child")

構建之後就是渲染、更新

接著看下嵌套組件

function Child() {
  return <div>child</div>
}
function Parent(){
  return (
   <Child>parent child</Child>
  )
}

React會調用React.createElement,並傳入以下參數

function Child() {
  return React.createElement("div", null, "child");
}

function Parent() {
  return React.createElement(Child, null, "parent child");
}

這裡我們看出父子組件的構建過程,首先對當前組件進行構建,接著進入到組件中,繼續構建,遵循的原則是從上到下

接著看看傳入多個組件

function Child() {
  return <div>child組件</div>
}
function Parent(){
  return (
    <div>
     <div>div元素</div>
     <Child />
    </div>
  )
}

在React.createElement會傳入以下參數

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

偏離一點點主題

下面的代碼可以輔助理解上面的內容

// 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>
  )
}

在上面兩種寫法中,第一種一定會報錯

因為第一種的構建參數是

React.createElement(RenderChild, { val: a },React.createElement("div", null, a.b))
此時a還是undefined

第二種構建參數是

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嵌套組件的構建的資料請關註WalkonNet其它相關文章!

推薦閱讀:

    None Found