ReactFiberClassComponent.new
在创建Component组件的时候,我们需要传入Updater,控制组件状态的更新。今天我们来看看Updater的源码,定义,看能学习到什么东西。
位置:react-reconciler\src\ReactFiberClassComponent.new.js
classComponentUpdater
// Updater 作为一个对象
const classComponentUpdater = {
// 属性是否挂载
isMounted,
// 入队设置状态state
enqueueSetState(inst, payload, callback) {
// 取得实例上的fiber
const fiber = getInstance(inst);
// 初始化事件时间
const eventTime = requestEventTime();
// 请求一条合适的车道
const lane = requestUpdateLane(fiber);
// 初始化一个update
const update = createUpdate(eventTime, lane);
// 完善update的负载和callback信息
update.payload = payload;
if (callback !== undefined && callback !== null) {
if (__DEV__) {
warnOnInvalidCallback(callback, 'setState');
}
update.callback = callback;
}
// 将update入队
enqueueUpdate(fiber, update, lane);
const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
if (root !== null) {
entangleTransitions(root, fiber, lane);
}
if (__DEV__) {
if (enableDebugTracing) {
if (fiber.mode & DebugTracingMode) {
const name = getComponentNameFromFiber(fiber) || 'Unknown';
logStateUpdateScheduled(name, lane, payload);
}
}
}
if (enableSchedulingProfiler) {
markStateUpdateScheduled(fiber, lane);
}
},
// 替换状态state方法,大同小异,component文中已经看过了
enqueueReplaceState(inst, payload, callback) {
const fiber = getInstance(inst);
const eventTime = requestEventTime();
const lane = requestUpdateLane(fiber);
const update = createUpdate(eventTime, lane);
update.tag = ReplaceState;
update.payload = payload;
if (callback !== undefined && callback !== null) {
if (__DEV__) {
warnOnInvalidCallback(callback, 'replaceState');
}
update.callback = callback;
}
enqueueUpdate(fiber, update, lane);
const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
if (root !== null) {
entangleTransitions(root, fiber, lane);
}
if (__DEV__) {
if (enableDebugTracing) {
if (fiber.mode & DebugTracingMode) {
const name = getComponentNameFromFiber(fiber) || 'Unknown';
logStateUpdateScheduled(name, lane, payload);
}
}
}
if (enableSchedulingProfiler) {
markStateUpdateScheduled(fiber, lane);
}
},
// 强制更新方法,同样见component一文
enqueueForceUpdate(inst, callback) {
const fiber = getInstance(inst);
const eventTime = requestEventTime();
const lane = requestUpdateLane(fiber);
const update = createUpdate(eventTime, lane);
update.tag = ForceUpdate;
if (callback !== undefined && callback !== null) {
if (__DEV__) {
warnOnInvalidCallback(callback, 'forceUpdate');
}
update.callback = callback;
}
enqueueUpdate(fiber, update, lane);
const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
if (root !== null) {
entangleTransitions(root, fiber, lane);
}
if (__DEV__) {
if (enableDebugTracing) {
if (fiber.mode & DebugTracingMode) {
const name = getComponentNameFromFiber(fiber) || 'Unknown';
logForceUpdateScheduled(name, lane);
}
}
}
if (enableSchedulingProfiler) {
markForceUpdateScheduled(fiber, lane);
}
},
};
checkShouldComponentUpdate
检查组件是否应该更新
function checkShouldComponentUpdate(
workInProgress,
ctor,
oldProps,
newProps,
oldState,
newState,
nextContext,
) {
// 先取得当前fiber的本地状态实例 instance
const instance = workInProgress.stateNode;
// 如果状态中用户定义了 shouldComponentUpdate方法
if (typeof instance.shouldComponentUpdate === 'function') {
// 传入shouldComponentUpdate方法当前新的Props和新的状态,以及下一个上下文
let shouldUpdate = instance.shouldComponentUpdate(
newProps,
newState,
nextContext,
);
if (__DEV__) {
if (
debugRenderPhaseSideEffectsForStrictMode &&
workInProgress.mode & StrictLegacyMode
) {
disableLogs();
try {
// Invoke the function an extra time to help detect side-effects.
shouldUpdate = instance.shouldComponentUpdate(
newProps,
newState,
nextContext,
);
} finally {
reenableLogs();
}
}
// 没有定义shouldComponentUpdate方法,报错
if (shouldUpdate === undefined) {
console.error(
'%s.shouldComponentUpdate(): Returned undefined instead of a ' +
'boolean value. Make sure to return true or false.',
getComponentNameFromType(ctor) || 'Component',
);
}
}
return shouldUpdate;
}
// 如果是pureComponent,浅比较Props和State
if (ctor.prototype && ctor.prototype.isPureReactComponent) {
return (
!shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
);
}
// 以上都没有返回值,则默认返回true
return true;
}
checkClassInstance
DEV模式下检查Fiber实例的定义
function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) {
// 获取fiber的状态实例
const instance = workInProgress.stateNode;
if (__DEV__) {
// 组件名
const name = getComponentNameFromType(ctor) || 'Component';
// 组件的render方法
const renderPresent = instance.render;
// 检查render方法是否存在
if (!renderPresent) {
if (ctor.prototype && typeof ctor.prototype.render === 'function') {
console.error(
'%s(...): No `render` method found on the returned component ' +
'instance: did you accidentally return an object from the constructor?',
name,
);
} else {
console.error(
'%s(...): No `render` method found on the returned component ' +
'instance: you may have forgotten to define `render`.',
name,
);
}
}
// 如果实例上有getInitialState方法但是实例并不是React类
if (
instance.getInitialState &&
!instance.getInitialState.isReactClassApproved &&
!instance.state
) {
console.error(
'getInitialState was defined on %s, a plain JavaScript class. ' +
'This is only supported for classes created using React.createClass. ' +
'Did you mean to define a state property instead?',
name,
);
}
// 如果实例有getDefaultProps方法但是实例不是React类
if (
instance.getDefaultProps &&
!instance.getDefaultProps.isReactClassApproved
)