如果你是 React 的初學者,一定會對 React 和 ReactDOM 感到迷惑。為什么要分成兩個包呢?害得我還要引入兩次,說好的減輕開發人員負擔呢,這丫的在搞什么飛機。帶着這個疑問,我們一起來康康 React 的“野心”。
ReactDOM獨立的歷史原因
React 在v0.14之前是沒有 ReactDOM 的,所有功能都包含在 React 里。從v0.14(2015-10)開始,React 才被拆分成React 和 ReactDOM。為什么要把 React 和 ReactDOM 分開呢?因為有了 ReactNative。React 只包含了 Web 和 Mobile 通用的核心部分,負責 Dom 操作的分到 ReactDOM 中,負責 Mobile 的包含在 ReactNative 中。具體參考v0.14的release:React v0.14 - React Blog。
ReactDom 只做和瀏覽器或DOM相關的操作,例如:ReactDOM.render() 和 ReactDOM.findDOMNode()。如果是服務器端渲染,可以 ReactDOM.renderToString()。React 不僅能通過 ReactDOM 和Web頁面打交道,還能用在服務器端SSR,移動端ReactNative和桌面端Electron。
e.g:
Web端React代碼
import React from 'react';
import ReactDOM from 'react-dom';
const App = () => (
<div>
<h1>Hello React</h1>
</div>
)
ReactDom.render(<App/>, document.getElementById('root'));
移動端的ReactNative代碼:
import React from 'react';
import {Text, View} from 'react-native';
const WelcomeScreen = () => (
<View>
<Text>Hello ReactNative</Text>
</View>
);
相同的是都需要import React from 'react'
。
而Web應用需要import ReactDOM from 'react-dom'
;
Mobile應用需要import {Text, View} from 'react-native'
React API
React
是 React 庫的入口,你可以使用<script>
或者import React from 'react'
方式引入。
組件
使用 React 組件可以將 UI 拆分為獨立且復用的代碼片段,每部分都可獨立維護。你可以通過子類 React.Component
或 React.PureComponent
來定義 React 組件。
React 組件也可以被定義為可被包裝的函數React.memo
。
創建 React 元素
強烈建議使用 JSX 來編寫你的 UI 組件。因為每個 JSX 元素都是調用 React.createElement()
的語法糖。像下面這樣:
import React from 'react'
function A() {
// ...other code
return <h1>前端桃園</h1>
}
等價於:
import React from 'react'
function A() {
// ...other code
return React.createElement("h1", null, "前端桃園");
}
上面的代碼經過 babel 轉化,會變成下面的代碼。因為從本質上講,JSX 只是為 React.createElement(component, props, ...children)
函數提供的語法糖。
轉換元素
React
提供了幾個用於操作元素的 API:
Fragments
React
還提供了用於減少不必要嵌套的組件。
Refs
Suspense
Suspense 使得組件可以“等待”某些操作結束后,再進行渲染。目前,Suspense 僅支持的使用場景是:通過 React.lazy
動態加載組件。它將在未來支持其它使用場景,如數據獲取等。
Hooks
Hooks 是 React 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性。Hook 擁有專屬文檔章節和單獨的 API 參考文檔:
ReactDOM API
可以使用<script>
或者import React from 'react'
方式引入。
react-dom
的 package 提供了可在應用頂層使用的 DOM(DOM-specific)方法,如果有需要,你可以把這些方法用於 React 模型以外的地方。不過一般情況下,大部分組件都不需要使用這個模塊。
總結
React 成為一個獨立的核心包之后,可以很方便的做擴展。React 只實現了邏輯上的核心基礎功能。而基於不同平台或是場景的功能則由擴展包來實現。例如,用與瀏覽器的ReactDOM,用於APP的 ReactNative,用於測試的 React-art,用於ssr的next.js 等等,你也可以基於 React 寫出自己的一套渲染方案。這就是拆分的好處,核心部分復用,各自平台差異性各自實現。