React原始碼分析

lansy發表於2019-03-04

元件是什麼樣的?

下面是一個簡單的元件
列印一下這個元件,發現其實是一個js物件,而不是真實的dom。
那麼react是如何將react元件生成js物件的呢?
這是因為我們在建立元件的時候,使用了extends.React.Component,即繼承了Component,看下Component的原始碼

function Component(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  // renderer.
  this.updater = updater || ReactNoopUpdateQueue;
}
Component.prototype.setState = function (partialState, callback) {}
Component.prototype.forceUpdate = function (callback) {}
複製程式碼

我們宣告瞭一個元件,繼承了Component,它的原型上有setState等方法。
小結

React原始碼分析

元件初始化

我們在react類和我們平時寫的js類都一樣,唯一的區別在與react類多了一個render()方法,輸出類似“這是A元件”的結構並掛載到真實DOM上,才能觸發元件的生命週期併成為DOM樹的一部分。
首先我們看下render()方法

React原始碼分析

發現render()實際是是呼叫一個React.creatEment(`div`,null),實際是實際是ReactElement方法
這個方法的作用是:每一個元件的物件都是通過React.creatEment()建立出來的ReactElement型別的物件,ReactElement物件記錄了元件的特徵,比如key,type,ref,props等,這些特徵與渲染成頁面息息相關。
下圖是ReactElement方法原始碼:

React原始碼分析

小結

React原始碼分析

元件的掛載

我們知道react是通過ReactDOM.render(component,monutNode)的形式進行掛載的(可以掛載自定義元件,原生dom,字串)
掛載過程是怎麼樣的呢?

ReactDOM.render實際呼叫了內部的ReactMount.render,進而執行ReactMount._renderSubtreeIntoContainer。從字面意思上就可以看出是將”子DOM”插入容器的邏輯,我們看下原始碼實現:

render: function (element, container, callback) {
    return renderSubtreeIntoContainer(null, element, container, false, callback);
  },
  function renderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback){}
複製程式碼

我們看下renderSubtreeIntoContainer的入參:

parentComponent:當前元件的父元件,第一次渲染時為null
children:要插入DOM中的元件,如helloWorld
container:要插入的容器,如document.getElementById(`root`)

小結

React原始碼分析

元件的生命週期

我們知道,根據ReactDOM.render()的入參型別不同,在內部通過工廠方法生成四種不同型別的封裝元件:

ReactEmptyComponent(空物件)

ReactTextComponent(字串)

ReactDOMComponent(原生dom)

ReactCompositeComponent(自定義元件,這個型別才會有生命週期)

在執行掛載流程時,通過執行每種封裝元件內部的mountComponent方法觸發生命週期,但顯然生命週期只在React自定義元件中存在,也就是ReactCompositeComponent。

小結

React原始碼分析
React原始碼分析

相關文章