一、setState不會當即改變state的值
二、setState會經過觸發組件的更新來觸發重繪
setState依次觸發如下4個組件的生命週期
1)shouldComponentUpdate(被調用時,state尚未更新,若是返回false,不會再觸發其餘生命周 期,可是state依然會被更新)
2)componentWillUpdate(被調用時state尚未被更新)
3)render(調用時state已經被更新)
4)componentDidUpdate
三、屢次連續的setState會進行合併react
//兩次連續setState this.setState({name: ‘xiaoming’}) this.setState({age: 24}) //至關於 this.setState({name: ‘xiaoming’, age: 24})
調用this.setState其實是調用this.updater.enqueueSetState,每一個ReactComponent對象在運行時都會被注入updater屬性,咱們經過打印Component實例可查看,如圖所示:
數組
知道了這個屬性,setState源碼就十分清晰了this
ReactComponent.prototype.setState = (partialState, callback) => { // this是組件實例 // 將setState、callbackfen放入updater的隊列中 this.updater.enqueueSetState(this, partialState) if(callback) { this.updater.enqueueCallback(this, callback, ’setState') } }
下面看一下真是調用的enqueueSetState方法spa
enqueueSetState: (publicInstance, partailState) { // 組件實例有一個_reactInternalInstance屬性,能夠當作獲取該屬性 var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, ’setState’) // 初始化實例的待更新隊列 var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []) queue.push(partailState) enqueueUpdate(internalInstance) }
enqueueSetState內調用的enqueueUpdateprototype
enqueueUpdate: (component) { //若是不是處於批量建立/更新組件的階段,就更新當前組件 // batchingStrategy是ReactDefaultBatchingStrategy對象的引用 if(!batchingStrategy.isBatchingUpdates) { batchingStrategy.batchedUpdates(enqueueUpdate, component) return; } // 若是處於批量更新階段,則放進髒數組中等待,等待更新 dirtyComponents.push(component) }
batchingStrategy.isBatchingUpdates,在react中只有兩個地方被更新,code
var ReactDefaultBatchingStrategy = { //標記是否處於批量更新/新建階段,默認是false isBatchingUpdates: false, //開啓批量更新方法 batchedUpdates: function(callback, a, b, c, d, e) { var alreadyBatchUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; ReactDefaultBatchingStrategy.isBatchingUpdates = true; //已經開啓了批量更新,調用callback回調,就是enqueueUpdate方法,進去從新等待 if(alreadyBatchUpdates) { return callback(a, b, c, d, e) } // 不然開啓事務,進行批量更新 Return transaction.perform(callback, null, a, b, c, d, e) } }