setState&forceUpdate
在react中触发状态更新的几种方式:
- ReactDOM.render
- this.setState
- this.forceUpdate
- useState
- useReducer
我们重点看下重点看下this.setState和this.forceUpdate,hook在第13章讲
- this.setState内调用this.updater.enqueueSetState,主要是将update加入updateQueue中
//ReactBaseClasses.js
Component.prototype.setState = function (partialState, callback) {
if (!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null)) {
{
throw Error( "setState(...): takes an object of state variables to update or a function which returns an object of state variables." );
}
}
this.updater.enqueueSetState(this, partialState, callback, 'setState');
};
//ReactFiberClassComponent.old.js
enqueueSetState(inst, payload, callback) {
const fiber = getInstance(inst);//fiber实例
const eventTime = requestEventTime();
const suspenseConfig = requestCurrentSuspenseConfig();
const lane = requestUpdateLane(fiber, suspenseConfig);//优先级
const update = createUpdate(eventTime, lane, suspenseConfig);//创建update
update.payload = payload;
if (callback !== undefined && callback !== null) {
//赋值回调
update.callback = callback;
}
enqueueUpdate(fiber, update);//update加入updateQueue
scheduleUpdateOnFiber(fiber, lane, eventTime);//调度update
}
enqueueUpdate用来将update加入updateQueue队列
//ReactUpdateQueue.old.js
export function enqueueUpdate<State>(fiber: Fiber, update: Update<State>) {
const updateQueue = fiber.updateQueue;
if (updateQueue === null) {
return;
}
const sharedQueue: SharedQueue<State> = (updateQueue: any).shared;
const pending = sharedQueue.pending;
if (pending === null) {
update.next = update;//与自己形成环状链表
} else {
update.next = pending.next;//加入链表的结尾
pending.next = update;
}
sharedQueue.pending = update;
}
- this.forceUpdate和this.setState一样,只是会让tag赋值ForceUpdate
//ReactBaseClasses.js
Component.prototype.forceUpdate = function(callback) {
this.updater.enqueueForceUpdate(this, callback, 'forceUpdate'