Open zhangxl2929 opened 5 years ago
相关源码:
function checkShouldComponentUpdate(
workInProgress,
ctor,
oldProps,
newProps,
oldState,
newState,
nextContext,
) {
const instance = workInProgress.stateNode;
// 如果组件中写了 shouldComponentUpdate 这个方法,那么就由这个方法判断是否需要重新渲染
if (typeof instance.shouldComponentUpdate === 'function') {
startPhaseTimer(workInProgress, 'shouldComponentUpdate');
const shouldUpdate = instance.shouldComponentUpdate(
newProps,
newState,
nextContext,
);
stopPhaseTimer();
if (__DEV__) {
warningWithoutStack(
shouldUpdate !== undefined,
'%s.shouldComponentUpdate(): Returned undefined instead of a ' +
'boolean value. Make sure to return true or false.',
getComponentName(ctor) || 'Component',
);
}
return shouldUpdate;
}
// 如果继承自 PureReactComponent,则简单的比较前后两个 props 和 state
if (ctor.prototype && ctor.prototype.isPureReactComponent) {
return (
!shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
);
}
// 默认返回 true,即进行重新渲染
return true;
}
componentWillReceiveProps 在什么时候会被调用
// 实例没有 getDerivedStateFromProps 和 getSnapshotBeforeUpdate这两个方法
const hasNewLifecycles =
typeof getDerivedStateFromProps === 'function' ||
typeof instance.getSnapshotBeforeUpdate === 'function';
// Note: During these life-cycles, instance.props/instance.state are what
// ever the previously attempted to render - not the "current". However,
// during componentDidUpdate we pass the "current" props.
// In order to support react-lifecycles-compat polyfilled components,
// Unsafe lifecycles should not be invoked for components using the new APIs.
if (
!hasNewLifecycles &&
(typeof instance.UNSAFE_componentWillReceiveProps === 'function' ||
typeof instance.componentWillReceiveProps === 'function')
) {
// 前后 props 或者 context 不全等时调用
if (oldProps !== newProps || oldContext !== nextContext) {
callComponentWillReceiveProps(
workInProgress,
instance,
newProps,
nextContext,
);
}
}
开发中遇到一个问题,组件的 props 明明变了,在组件的 componentWillReceiveProps 中打了断点,程序走到这里了也确实 this.props.a !== nextProps.a 但是却没有重新渲染组件,根本没有走到组件的 render 函数中去。 很纳闷,一直的认知是当组件的 props 变了组件就会重新渲染,但是现在看起来似乎不尽然。 于是决定去看看源码。