启动模式和渲染流程
启动模式
在 React 18 中,React 应用有两种启动模式:
legacy
模式:ReactDOM.render(<App />, document.getElementById('root'))
这个模式可能不支持这些新功能(concurrent 支持的所有功能)concurrent
模式:ReactDOM.createRoot(rootNode).render(<App />)
这个模式开启了所有的新功能(是 React 18 的默认模式)
blocking
模式
在 React 17 中,还有一种 blocking
模式,它是开启部分 concurrent
模式特性的中间模式,是作为迁移到 concurrent
模式的第一个步骤
js
ReactDOM.createBlockingRoot(rootNode).render(<App />)
这个模式 React 18 中已经被移除
各种模式对特性的支持
legacy 模式 | blocking 模式 | concurrent 模式 | |
---|---|---|---|
String Refs | ✅ | 🚫** | 🚫** |
Legacy Context | ✅ | 🚫** | 🚫** |
findDOMNode | ✅ | 🚫** | 🚫** |
Suspense | ✅ | ✅ | ✅ |
SuspenseList | 🚫 | ✅ | ✅ |
Suspense SSR + Hydration | 🚫 | ✅ | ✅ |
Progressive Hydration | 🚫 | ✅ | ✅ |
Selective Hydration | 🚫 | 🚫 | ✅ |
Cooperative Multitasking | 🚫 | 🚫 | ✅ |
Automatic batching of multiple setStates | 🚫* | ✅ | ✅ |
Priority-based Rendering | 🚫 | 🚫 | ✅ |
Interruptible Prerendering | 🚫 | 🚫 | ✅ |
useTransition | 🚫 | 🚫 | ✅ |
useDeferredValue | 🚫 | 🚫 | ✅ |
Suspense Reveal "Train" | 🚫 | 🚫 | ✅ |
*:legacy
模式在合成事件中有自动批处理的功能,但仅限于一个浏览器任务。非 React 事件想使用这个功能必须使用 unstable_batchedUpdates
。在 blocking
模式和 concurrent
模式下,所有的 setState
在默认情况下都是批处理的
**:会在开发中发出警告
TIP
- React 通过不同的入口函数开启不同模式,且模式的变化影响的是整个应用的工作方式,所以无法只针对某个组件开启不同模式
- 这几种模式下的
fiber.mode
的值有所不同
ts
export type RootTag = 0 | 1
export const LegacyRoot = 0
export const ConcurrentRoot = 1
渲染流程
React 应用程序的渲染流程可以分为三个阶段:
- 初始化阶段
render
阶段:即 Reconciler 工作的阶段,render
阶段会调用组件的render
方法获取组件的React Element
,并构建Fiber
树commit
阶段:即 Renderer 工作的阶段,commit
阶段会把render
阶段提交的信息渲染在页面上
render
与 commit
阶段统称为 work
,即 React 在工作中。如果任务正在 Scheduler 内调度就不属于 work
阶段