源码看React setState漫谈(二)
前面写过一篇setState漫谈(一)谈论了用户操作到页面渲染的过程,相信大家对React的setState机制有了一定了解。这里我们看看setState在生命周期的各个流程里调用都会发生什么。 更新流程结论:
componentWillReceiveProps中调用setState还是先放上流程图: 首先我们知道React是在 var NESTED_UPDATES = { initialize: function() { this.dirtyComponentsLength = dirtyComponents.length; },close: function() { if (this.dirtyComponentsLength !== dirtyComponents.length) { dirtyComponents.splice(0,this.dirtyComponentsLength); flushBatchedUpdates(); } else { dirtyComponents.length = 0; } },}; Object.assign(ReactUpdatesFlushTransaction.prototype,Transaction,{ getTransactionWrappers: function() { return TRANSACTION_WRAPPERS; },destructor: function() { ..... },perform: function(method,scope,a) { ...... },}); 然后我们看第一次更新都发生了什么? performUpdateIfNecessary: function (transaction) { if (this._pendingElement != null) { ReactReconciler.receiveComponent(this,this._pendingElement,transaction,this._context); } else if (this._pendingStateQueue !== null || this._pendingForceUpdate) { this.updateComponent(transaction,this._currentElement,this._context,this._context); } else { this._updateBatchNumber = null; } }, 第一次进来 updateComponent: function (transaction,prevParentElement,nextParentElement,prevUnmaskedContext,nextUnmaskedContext) { var inst = this._instance; var willReceive = false; var nextContext; var prevProps = prevParentElement.props; var nextProps = nextParentElement.props; .... inst.componentWillReceiveProps(nextProps,nextContext); //将新的state合并到更新队列中,此时nextState为最新的state var nextState = this._processPendingState(nextProps,nextContext); var shouldUpdate = true; if (!this._pendingForceUpdate) { shouldUpdate = inst.shouldComponentUpdate(nextProps,nextState,nextContext); } this._updateBatchNumber = null; if (shouldUpdate) { this._pendingForceUpdate = false; this._performComponentUpdate(nextParentElement,nextProps,nextContext,nextUnmaskedContext); } }, 我们看到进入 var nextState = this._processPendingState(nextProps,nextContext); _processPendingState: function (props,context) { var inst = this._instance; var queue = this._pendingStateQueue; var replace = this._pendingReplaceState; this._pendingReplaceState = false; this._pendingStateQueue = null; if (!queue) { return inst.state; } if (replace && queue.length === 1) { return queue[0]; } var nextState = _assign({},replace ? queue[0] : inst.state); return nextState; }, 可以看到这里根据pendingStateQueue,更新了state并赋给了nextState,同时删除了pendingStateQueue 接下来就是 performUpdateIfNecessary: function (transaction) { if (this._pendingStateQueue !== null || this._pendingForceUpdate) { this.updateComponent(transaction, 因为上面_pendingStateQueue已经被删除,所以这次是不会触发新一轮的update. coponentShouldUpdate,componentWillUpdate,render和componentDidUpdate这几个和componentWIllReceiveProps有什么区别?最大的区别就在于。他们都是在 细节补充也许有人会问为什么setState对_pendingStateQueue的更新会同步到ReactCompositeComponent里面。那我们就来看看 首先,_pendingStateQueue来自enqueueReplaceState var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); internalInstance._pendingStateQueue = [completeState]; internalInstance._pendingReplaceState = true; 其实这里的internalInstance就是ReactElement对象。一路跟着代码跟到ReactReconciler,一直到 internalInstance.performUpdateIfNecessary(transaction); 可我们发现internalInstance并没有performUpdateIfNecessary方法啊,其实这是定义在原型上的方法。我们在instantiateReactComponent中发现了端倪: Object.assign( ReactCompositeComponentWrapper.prototype,ReactCompositeComponent,{ _instantiateReactComponent: instantiateReactComponent,},); 所以,composite的调用者就是internalInstance,也就是我们在调用栈里传来传去的component,而我们从头到尾维护的也是internalInstance的属性 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |