跳到主要内容

state原理

state 到底是同步还是异步的?

batchUpdate 批量更新? 批量更新被打破的条件?

React三种模式,不同更新逻辑

legacy 模式 blocking 模式 concurrent 模式

React 更新流程

类组件 setState 和函数组件 useState

类组件

① pureComponent 可以对 state 和 props 进行浅比较,如果没有发生变化,那么组件不更新。 ② shouldComponentUpdate 生命周期可以通过判断前后 state 变化来决定组件需不需要更新,需要更新返回true,否则返回false。

调用 setState 方法,实际上是 React 底层调用 Updater 对象上的 enqueueSetState 方法。

enqueueSetState 作用实际很简单,就是创建一个 update ,然后放入当前 fiber 对象的待更新队列中,最后开启调度更新,进入上述讲到的更新流程。

State 批量更新正是和事件系统息息相关

export function batchedUpdates(fn, a, b) {
if (isInsideEventHandler) {
// If we are currently inside another batch, we need to wait until it
// fully completes before restoring state.
return fn(a, b);
}
isInsideEventHandler = true;
try {
return batchedUpdatesImpl(fn, a, b); // fn为事件的回调函数,里面进行了多次setState,从代码可以看出,这边直接一次性在fn中执行
} finally {
isInsideEventHandler = false;
finishEventHandler();
}
}

打破批量更新,给batchedUpdatesfn包一层作用域,比如放到 异步回调

使用 异步回调 打破了批量更新,又想使用批量更新,可以手动批量更新 —— unstable_batchedUpdates

import ReactDOM from 'react-dom'
const { unstable_batchedUpdates } = ReactDOM

setTimeout(()=>{
unstable_batchedUpdates(()=>{
this.setState({ number:this.state.number + 1 })
console.log(this.state.number)
this.setState({ number:this.state.number + 1})
console.log(this.state.number)
this.setState({ number:this.state.number + 1 })
console.log(this.state.number)
})
})
提示

unstable_batchedUpdates 可以用于 Ajax 数据交互之后,合并多次 setState,或者是多次 useState 。原因很简单,所有的数据交互都是在异步环境下,如果没有批量更新处理,一次数据交互多次改变 state 会促使视图多次渲染。

ReactDOM.flushSync()回调,提供更高优化级

函数组件

useState

 [ state , dispatch ] = useState(initData)

如何监听 state 变化?

把 state 作为依赖项传入 useEffect 第二个参数 deps。当传入的 state 发生变化行,触发 useEffect 第一个参数回调函数的执行

提示

useEffect 初始化会默认执行一次