You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionenqueueUpdate(component){ensureInjected();// Various parts of our code (such as ReactCompositeComponent's// _renderValidatedComponent) assume that calls to render aren't nested;// verify that that's the case. (This is called by each top-level update// function, like setProps, setState, forceUpdate, etc.; creation and// destruction of top-level components is guarded in ReactMount.)if(!batchingStrategy.isBatchingUpdates){batchingStrategy.batchedUpdates(enqueueUpdate,component);return;}dirtyComponents.push(component);}
为了实现上面的逻辑判断,React 将整个的函数执行过程包裹上了 Transaction,在函数执行前与执行后分别有 initialize 和 close 两个方法。这样的话 React 就有时机在函数执行过程中,涉及到 setState 的执行,都将缓存下来,在 close 的时候进入到 React 的 state 更新逻辑进行更新判断操作,并最终更新到前台的 DOM 上。 initialize、close源码
setState 的源码实现
在 setState 的源码实现中,传递过来的参数就被定义成了 partialState,从参数名以及参数的说明中就可以看到,这只是 state 的一部分。
默认都会调用 this.updater.enqueueSetState(this, partialState) 将 state 放进更新队列中去。
而如果有传递回调函数过来的话,会执行 this.updater.enqueueCallback(this, callback).
ReactComponent.prototype.setState=function(partialState,callback){invariant(typeofpartialState==='object'||typeofpartialState==='function'||partialState==null,'setState(...): takes an object of state variables to update or a '+'function which returns an object of state variables.');if(__DEV__){warning(partialState!=null,'setState(...): You passed an undefined or null state object; '+'instead, use forceUpdate().');}this.updater.enqueueSetState(this,partialState);if(callback){this.updater.enqueueCallback(this,callback);}};
更新队列 ReactUpdateQueue 的定义
在上面的 setState 定义中,我们可以看到有一个 updater 的调用
functionReactComponent(props,context,updater){this.props=props;this.context=context;this.refs=emptyObject;// We initialize the default updater but the real one gets injected by the// renderer.this.updater=updater||ReactNoopUpdateQueue;}ReactComponent.prototype.isReactComponent={};
functionenqueueUpdate(component){ensureInjected();// Various parts of our code (such as ReactCompositeComponent's// _renderValidatedComponent) assume that calls to render aren't nested;// verify that that's the case. (This is called by each top-level update// function, like setProps, setState, forceUpdate, etc.; creation and// destruction of top-level components is guarded in ReactMount.)if(!batchingStrategy.isBatchingUpdates){batchingStrategy.batchedUpdates(enqueueUpdate,component);return;}dirtyComponents.push(component);}
ensureInjected实现:
functionensureInjected(){invariant(ReactUpdates.ReactReconcileTransaction&&batchingStrategy,'ReactUpdates: must inject a reconcile transaction class and batching '+'strategy');}
注入了两个部分,ReactReconcileTransaction 以及 batchingStrategy。
ReactReconcileTransaction 主要用于在更新 state 时,页面 UI 元素的修正以及在执行生命周期函数时,处理好生命周期函数与其他用户自定义函数之间的执行顺序与逻辑
前言
我在业务中经常用到setState,自以为对setState已经非常对了解,直到某一天遇到一个关于state批量更新的面试题,发现自己好像对setState的认识也没有那么全面,所以写这篇文章主要是希望彻底搞清楚setState的更新机制。
setState的更新策略
React中的setState有Batch模式(批量更新模式)和普通模式。
普通模式下,setState能够即时更新state,重新调用 render 方法,然后把render方法所渲染的最新的内容显示到页面上。
Batch模式下,React不会立刻修改state。而是把这个对象放到一个更新队列中,稍后才会从队列中把新的状态提取出来合并到 state中,然后再触发组件更新。
批量更新
react的setState是一个异步方法,React 会将所有的 setState 方法打包成一次进行更新,每次修改 state 都会进行更新。这样的设计主要是为了提高 UI 更新的性能,
我们知道 React 中 state 的改变会导致 UI 的更新。如果想要进行同步操作逻辑有两种方法。
1.通过异步实现
2.通过回调函数实现
判断批量更新
在更新逻辑的部分,可以看到 React 会通过 batchingStrategy.isBatchingUpdates 判断当前的逻辑状态下是否需要进行批量更新
为了实现上面的逻辑判断,React 将整个的函数执行过程包裹上了 Transaction,在函数执行前与执行后分别有 initialize 和 close 两个方法。这样的话 React 就有时机在函数执行过程中,涉及到 setState 的执行,都将缓存下来,在 close 的时候进入到 React 的 state 更新逻辑进行更新判断操作,并最终更新到前台的 DOM 上。
initialize、close源码
setState 的源码实现
在 setState 的源码实现中,传递过来的参数就被定义成了 partialState,从参数名以及参数的说明中就可以看到,这只是 state 的一部分。
默认都会调用 this.updater.enqueueSetState(this, partialState) 将 state 放进更新队列中去。
而如果有传递回调函数过来的话,会执行 this.updater.enqueueCallback(this, callback).
更新队列 ReactUpdateQueue 的定义
在上面的 setState 定义中,我们可以看到有一个 updater 的调用
enqueueSetState 的定义
enqueueUpdate的实现
ReactUpdates 中的 enqueueUpdate
ensureInjected实现:
注入了两个部分,ReactReconcileTransaction 以及 batchingStrategy。
ReactReconcileTransaction 主要用于在更新 state 时,页面 UI 元素的修正以及在执行生命周期函数时,处理好生命周期函数与其他用户自定义函数之间的执行顺序与逻辑
现在我们可以看一下面试题了
搬运自:
The text was updated successfully, but these errors were encountered: