鍍金池/ 問答/HTML/ 想問下為什么需要遞歸調(diào)用mountComponent,不是在一開始就已經(jīng)調(diào)用cl

想問下為什么需要遞歸調(diào)用mountComponent,不是在一開始就已經(jīng)調(diào)用class內(nèi)部的render進行全部渲染了嗎

如果按照遞歸這個邏輯的話每次都會調(diào)用inst.render(),但是class內(nèi)部的render方法是一開始就寫好了的,每次都渲染同一個return值嗎?比如:

class Demo extends React.Component {
    constructor(...args) {
        super(...args);
    }
    render() {
        return <div>
            <span>123</span>
            <span>12345</span>
        </div>
    }
}  

為什么需要遞歸調(diào)用mountComponent,不是在一開始就已經(jīng)調(diào)用class內(nèi)部的render進行全部渲染了嗎?是不是像下面那樣進行一個個createElement進行渲染的,比如先是div,第二次遞歸是span進行render,謝謝

React.createElement(
        'div',    // type,標簽名,原生DOM對象為String
        null,
        React.createElement('span', null, '123'),   // children,子元素
        React.createElement('span', null, '12345'),
)

下面是部分源碼,react版本是15.6.0,git reset --hard 911603b

// 如果不是stateless,即無狀態(tài)組件,則調(diào)用render,返回ReactElement
if (renderedElement === undefined) {
  renderedElement = this._renderValidatedComponent();
}

_renderValidatedComponent: function () {
    var renderedComponent;
    ReactCurrentOwner.current = this;
    try {
      renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext();
    } finally {
      ReactCurrentOwner.current = null;
    }
    return renderedComponent;
},

_renderValidatedComponentWithoutOwnerOrContext: function () {
    var inst = this._instance;
    // 調(diào)用render方法,得到ReactElement。JSX經(jīng)過babel轉(zhuǎn)譯后其實就是createElement()方法。這一點在前面也講解過
    var renderedComponent = inst.render();
    return renderedComponent;
},

this._renderedComponent = this._instantiateReactComponent(renderedElement);

// 遞歸渲染,渲染子組件
var markup = ReactReconciler.mountComponent(this._renderedComponent, transaction, nativeParent, nativeContainerInfo, this._processChildContext(context));

原文鏈接

回答
編輯回答
萢萢糖

沒有閱讀過react源碼,只看過部分vue 代碼,大概 題主 有點理解性錯誤

為什么需要遞歸調(diào)用mountComponent,不是在一開始就已經(jīng)調(diào)用class內(nèi)部的render進行全部渲染了嗎?是不是像下面那樣進行一個個createElement進行渲染的,比如先是div,第二次遞歸是span進行render,謝謝
React.createElement(
        'div',    // type,標簽名,原生DOM對象為String
        null,
        React.createElement('span', null, '123'),   // children,子元素
        React.createElement('span', null, '12345'),
)

個人推斷,這個只是 react 內(nèi)部渲染函數(shù),并沒有執(zhí)行 你編寫 class內(nèi)部的render,具體執(zhí)行要看react 如何去做
react 是個框架。你執(zhí)行了 react.render并不是實際直接渲染class內(nèi)部的render,而是 react框架 在 內(nèi)部執(zhí)行了一大堆東西后 最終 執(zhí)行你 class 的 render 函數(shù)。也就是 mountComponent 函數(shù)
但也可能我推斷是錯誤的。
題主也可以 去看看 preact,這個壓縮只有 3kb。精簡 且 可讀性高。

2017年1月16日 08:12