前言
ReactDOM.render
函數(shù)是整個 React 應用程序首次渲染的入口函數(shù),你對它了解多少呢?本節(jié)主要介紹 ReactDOM 對象有哪些屬性與方法,ReactDOM.render
函數(shù)在的三個重要參數(shù)分別是什么,以及函數(shù)返回值是什么。
ReactDOM 對象
ReactDOM 對象的定義,見代碼示例 1.2.1。
注:本專欄引用的 React 源碼版本為 v16.9。
// 源碼位置:packages/react-dom/src/client/ReactDOM.js
const ReactDOM = {
findDOMNode: function(...) { ... },
hydrate: function(...) { ... },
render: function (element, container, callback) {
// 會先檢驗container是否有效,無效則停止執(zhí)行且拋出錯誤
// ...
return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
},
unstable_renderSubtreeIntoContainer: function(...) {},
unmountComponentAtNode: function(...) {}
// ...
}
ReactDOM 對象上面有findDOMNode
、hydrate
和render
等多個函數(shù)。其中ReactDOM.render
函數(shù)有三個參數(shù)和一個返回值。下面內容將會對這三個參數(shù)和返回值進行詳細說明。
理解 ReactDOM.render 函數(shù)的三個參數(shù)
ReactDOM.render( ... )
的基本用法見代碼示例 1.2.2。
import React from 'react';
import ReactDOM from 'react-dom';
import UpdateCounter from './pages/UpdateCounter';
ReactDOM.render(<UpdateCounter name="Taylor" />, document.getElementById('root'));
在代碼示例 1.2.1 中,傳入ReactDOM.render
函數(shù)的兩個參數(shù)分別是<UpdateCounter name="Taylor" />
和document.getElementById('root')
。第二個參數(shù)很明顯是 DOM 元素,也就是 React 應用程序最終渲染在頁面中的容器。那么,我們該如何理解第一個參數(shù)呢?
UpdateCounter
是由 class
聲明的一個「類」,它在 React 中被稱為組件( component )。React 提供了 JSX 語法,基于 JSX 語法在函數(shù)或者「類」的兩側分別加上<
和/>
就變成了元素( element )。因此,<UpdateCounter name="Taylor" />
就是一個 React 元素。在第二章中會詳細介紹 React 組件和 React 元素。
第三個參數(shù)是應用程序渲染完成后的回調函數(shù),這個參數(shù)是可選項,React 會在應用程序渲染完成后檢查是否有回調函數(shù),如果有則調用該回調函數(shù)。
ReactDOM.render
函數(shù)除了執(zhí)行渲染任務外還有自己的返回值即legacyRenderSubtreeIntoContainer
函數(shù)的執(zhí)行結果。那么,legacyRenderSubtreeIntoContainer
函數(shù)的執(zhí)行結果是什么呢?
ReactDOM.render 函數(shù)的返回值
在 React 源碼中,legacyRenderSubtreeIntoContainer
函數(shù)內部通過return
的形式又嵌套了多層函數(shù)。為了方便看到ReactDOM.render
函數(shù)最終的返回值,使用console.log(...)
將函數(shù)執(zhí)行結果輸出,見代碼示例 1.2.3。
console.log('返回值',
ReactDOM.render(
<UpdateCounter name="Taylor" />, document.getElementById('root'), () => {console.log('渲染完成')}
)
);
// 輸出結果
UpdateCounter: {
context: {},
handleClick: ? (),
props: {name: "Taylor"},
refs: {},
state: {count: 0, text: "點擊計數(shù)"},
// 更新觸發(fā)器
updater: {isMounted: ?, enqueueSetState: ?, enqueueReplaceState: ?, enqueueForceUpdate: ?},
// 存儲了首次渲染完成后對應的Fiber結點信息
_reactInternalFiber: FiberNode {tag: 1, key: null, stateNode: UpdateCounter, elementType: …},
_reactInternalInstance: {_processChildContext: ?},
isMounted: (...),
replaceState: (...),
// 繼承于React.Component
__proto__: Component,
}
ReactDOM.render
函數(shù)的返回值是當前應用程序根組件的實例。組件實例是 React 應用程序運行時在內存中的一種臨時狀態(tài),組件實例的屬性包括了自身類定義的屬性以及繼承于React.Component
的屬性。在UpdateCounter
實例中,state
和handleClick
為自身類的屬性,而context
,props
和updater
等則繼承于React.Component
。
小結
本章主要介紹了在研究 React 內部運行機制方面的一些思路與切入點以及 React 應用程序的首次渲染入口—ReactDOM.render
函數(shù)。下一章將會更加詳細的介紹 React 世界中的一些基礎概念,如 React 組件,組件繼承原理,React 元素設計思想,React 組件實例的作用以及組件與元素之間的關系 等。