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();
}
}
打破批量更新,给batchedUpdates
的fn
包一层作用域,比如放到 异步回调中
使用 异步回调 打破了批量更新,又想使用批量更新,可以手动批量更新 —— 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 初始化会默认执行一次