React16源码: React中的updateClassComponent的源码实现

时间:2024-01-22 18:47:52
function constructClassInstance( workInProgress: Fiber, ctor: any, props: any, renderExpirationTime: ExpirationTime, ): any { // 先跳过 context 相关 let isLegacyContextConsumer = false; let unmaskedContext = emptyContextObject; let context = null; const contextType = ctor.contextType; // if (typeof contextType === 'object' && contextType !== null) { // 跳过 DEV if (__DEV__) { if ( contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor) ) { didWarnAboutInvalidateContextType.add(ctor); warningWithoutStack( false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext(). ' + 'Did you accidentally pass the Context.Provider instead?', getComponentName(ctor) || 'Component', ); } } context = readContext((contextType: any)); } else { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); const contextTypes = ctor.contextTypes; isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined; context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject; } // Instantiate twice to help detect side-effects. if (__DEV__) { if ( debugRenderPhaseSideEffects || (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) ) { new ctor(props, context); // eslint-disable-line no-new } } // ctor 是 construct 的一个缩写 这个 ctor 就是在 ReactElement当中 // 存在的那个type,也就是 class component 定义的那个class // 传入 props和context,对应于 ReactBaseClasses.js 里面,Component 函数 接收的这两个参数 // 第三个参数 updater 后面在 adoptClassInstance 里面设置 const instance = new ctor(props, context); // 获取 state const state = (workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null); adoptClassInstance(workInProgress, instance); if (__DEV__) { if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) { const componentName = getComponentName(ctor) || 'Component'; if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); warningWithoutStack( false, '`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName, ); } } // If new component APIs are defined, "unsafe" lifecycles won't be called. // Warn about these lifecycles if they are present. // Don't warn about react-lifecycles-compat polyfilled methods though. if ( typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function' ) { let foundWillMountName = null; let foundWillReceivePropsName = null; let foundWillUpdateName = null; if ( typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true ) { foundWillMountName = 'componentWillMount'; } else if (typeof instance.UNSAFE_componentWillMount === 'function') { foundWillMountName = 'UNSAFE_componentWillMount'; } if ( typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true ) { foundWillReceivePropsName = 'componentWillReceiveProps'; } else if ( typeof instance.UNSAFE_componentWillReceiveProps === 'function' ) { foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps'; } if ( typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true ) { foundWillUpdateName = 'componentWillUpdate'; } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') { foundWillUpdateName = 'UNSAFE_componentWillUpdate'; } if ( foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null ) { const componentName = getComponentName(ctor) || 'Component'; const newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()'; if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(componentName); warningWithoutStack( false, 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-async-component-lifecycle-hooks', componentName, newApiName, foundWillMountName !== null ? `\n ${foundWillMountName}` : '', foundWillReceivePropsName !== null ? `\n ${foundWillReceivePropsName}` : '', foundWillUpdateName !== null ? `\n ${foundWillUpdateName}` : '', ); } } } } // Cache unmasked context so we can avoid recreating masked context unless necessary. // ReactFiberContext usually updates this cache but can't for newly-created instances. if (isLegacyContextConsumer) { cacheContext(workInProgress, unmaskedContext, context); } return instance; }