1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. import type {Fiber} from './ReactInternalTypes';
    
  11. import type {Lanes} from './ReactFiberLane';
    
  12. import type {UpdateQueue} from './ReactFiberClassUpdateQueue';
    
  13. 
    
  14. import {
    
  15.   LayoutStatic,
    
  16.   Update,
    
  17.   Snapshot,
    
  18.   MountLayoutDev,
    
  19. } from './ReactFiberFlags';
    
  20. import {
    
  21.   debugRenderPhaseSideEffectsForStrictMode,
    
  22.   disableLegacyContext,
    
  23.   enableDebugTracing,
    
  24.   enableSchedulingProfiler,
    
  25.   enableLazyContextPropagation,
    
  26. } from 'shared/ReactFeatureFlags';
    
  27. import ReactStrictModeWarnings from './ReactStrictModeWarnings';
    
  28. import {isMounted} from './ReactFiberTreeReflection';
    
  29. import {get as getInstance, set as setInstance} from 'shared/ReactInstanceMap';
    
  30. import shallowEqual from 'shared/shallowEqual';
    
  31. import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
    
  32. import getComponentNameFromType from 'shared/getComponentNameFromType';
    
  33. import assign from 'shared/assign';
    
  34. import isArray from 'shared/isArray';
    
  35. import {REACT_CONTEXT_TYPE, REACT_PROVIDER_TYPE} from 'shared/ReactSymbols';
    
  36. 
    
  37. import {resolveDefaultProps} from './ReactFiberLazyComponent';
    
  38. import {
    
  39.   DebugTracingMode,
    
  40.   NoMode,
    
  41.   StrictLegacyMode,
    
  42.   StrictEffectsMode,
    
  43. } from './ReactTypeOfMode';
    
  44. 
    
  45. import {
    
  46.   enqueueUpdate,
    
  47.   entangleTransitions,
    
  48.   processUpdateQueue,
    
  49.   checkHasForceUpdateAfterProcessing,
    
  50.   resetHasForceUpdateBeforeProcessing,
    
  51.   createUpdate,
    
  52.   ReplaceState,
    
  53.   ForceUpdate,
    
  54.   initializeUpdateQueue,
    
  55.   cloneUpdateQueue,
    
  56. } from './ReactFiberClassUpdateQueue';
    
  57. import {NoLanes} from './ReactFiberLane';
    
  58. import {
    
  59.   cacheContext,
    
  60.   getMaskedContext,
    
  61.   getUnmaskedContext,
    
  62.   hasContextChanged,
    
  63.   emptyContextObject,
    
  64. } from './ReactFiberContext';
    
  65. import {readContext, checkIfContextChanged} from './ReactFiberNewContext';
    
  66. import {requestUpdateLane, scheduleUpdateOnFiber} from './ReactFiberWorkLoop';
    
  67. import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing';
    
  68. import {
    
  69.   markForceUpdateScheduled,
    
  70.   markStateUpdateScheduled,
    
  71.   setIsStrictModeForDevtools,
    
  72. } from './ReactFiberDevToolsHook';
    
  73. 
    
  74. const fakeInternalInstance: {
    
  75.   _processChildContext?: () => empty,
    
  76. } = {};
    
  77. 
    
  78. let didWarnAboutStateAssignmentForComponent;
    
  79. let didWarnAboutUninitializedState;
    
  80. let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
    
  81. let didWarnAboutLegacyLifecyclesAndDerivedState;
    
  82. let didWarnAboutUndefinedDerivedState;
    
  83. let didWarnAboutDirectlyAssigningPropsToState;
    
  84. let didWarnAboutContextTypeAndContextTypes;
    
  85. let didWarnAboutInvalidateContextType;
    
  86. let didWarnOnInvalidCallback;
    
  87. 
    
  88. if (__DEV__) {
    
  89.   didWarnAboutStateAssignmentForComponent = new Set<string>();
    
  90.   didWarnAboutUninitializedState = new Set<string>();
    
  91.   didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set<string>();
    
  92.   didWarnAboutLegacyLifecyclesAndDerivedState = new Set<string>();
    
  93.   didWarnAboutDirectlyAssigningPropsToState = new Set<string>();
    
  94.   didWarnAboutUndefinedDerivedState = new Set<string>();
    
  95.   didWarnAboutContextTypeAndContextTypes = new Set<string>();
    
  96.   didWarnAboutInvalidateContextType = new Set<string>();
    
  97.   didWarnOnInvalidCallback = new Set<string>();
    
  98. 
    
  99.   // This is so gross but it's at least non-critical and can be removed if
    
  100.   // it causes problems. This is meant to give a nicer error message for
    
  101.   // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
    
  102.   // ...)) which otherwise throws a "_processChildContext is not a function"
    
  103.   // exception.
    
  104.   Object.defineProperty(fakeInternalInstance, '_processChildContext', {
    
  105.     enumerable: false,
    
  106.     value: function (): empty {
    
  107.       throw new Error(
    
  108.         '_processChildContext is not available in React 16+. This likely ' +
    
  109.           'means you have multiple copies of React and are attempting to nest ' +
    
  110.           'a React 15 tree inside a React 16 tree using ' +
    
  111.           "unstable_renderSubtreeIntoContainer, which isn't supported. Try " +
    
  112.           'to make sure you have only one copy of React (and ideally, switch ' +
    
  113.           'to ReactDOM.createPortal).',
    
  114.       );
    
  115.     },
    
  116.   });
    
  117.   Object.freeze(fakeInternalInstance);
    
  118. }
    
  119. 
    
  120. function warnOnInvalidCallback(callback: mixed, callerName: string) {
    
  121.   if (__DEV__) {
    
  122.     if (callback === null || typeof callback === 'function') {
    
  123.       return;
    
  124.     }
    
  125.     const key = callerName + '_' + (callback: any);
    
  126.     if (!didWarnOnInvalidCallback.has(key)) {
    
  127.       didWarnOnInvalidCallback.add(key);
    
  128.       console.error(
    
  129.         '%s(...): Expected the last optional `callback` argument to be a ' +
    
  130.           'function. Instead received: %s.',
    
  131.         callerName,
    
  132.         callback,
    
  133.       );
    
  134.     }
    
  135.   }
    
  136. }
    
  137. 
    
  138. function warnOnUndefinedDerivedState(type: any, partialState: any) {
    
  139.   if (__DEV__) {
    
  140.     if (partialState === undefined) {
    
  141.       const componentName = getComponentNameFromType(type) || 'Component';
    
  142.       if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
    
  143.         didWarnAboutUndefinedDerivedState.add(componentName);
    
  144.         console.error(
    
  145.           '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
    
  146.             'You have returned undefined.',
    
  147.           componentName,
    
  148.         );
    
  149.       }
    
  150.     }
    
  151.   }
    
  152. }
    
  153. 
    
  154. function applyDerivedStateFromProps(
    
  155.   workInProgress: Fiber,
    
  156.   ctor: any,
    
  157.   getDerivedStateFromProps: (props: any, state: any) => any,
    
  158.   nextProps: any,
    
  159. ) {
    
  160.   const prevState = workInProgress.memoizedState;
    
  161.   let partialState = getDerivedStateFromProps(nextProps, prevState);
    
  162.   if (__DEV__) {
    
  163.     if (
    
  164.       debugRenderPhaseSideEffectsForStrictMode &&
    
  165.       workInProgress.mode & StrictLegacyMode
    
  166.     ) {
    
  167.       setIsStrictModeForDevtools(true);
    
  168.       try {
    
  169.         // Invoke the function an extra time to help detect side-effects.
    
  170.         partialState = getDerivedStateFromProps(nextProps, prevState);
    
  171.       } finally {
    
  172.         setIsStrictModeForDevtools(false);
    
  173.       }
    
  174.     }
    
  175.     warnOnUndefinedDerivedState(ctor, partialState);
    
  176.   }
    
  177.   // Merge the partial state and the previous state.
    
  178.   const memoizedState =
    
  179.     partialState === null || partialState === undefined
    
  180.       ? prevState
    
  181.       : assign({}, prevState, partialState);
    
  182.   workInProgress.memoizedState = memoizedState;
    
  183. 
    
  184.   // Once the update queue is empty, persist the derived state onto the
    
  185.   // base state.
    
  186.   if (workInProgress.lanes === NoLanes) {
    
  187.     // Queue is always non-null for classes
    
  188.     const updateQueue: UpdateQueue<any> = (workInProgress.updateQueue: any);
    
  189.     updateQueue.baseState = memoizedState;
    
  190.   }
    
  191. }
    
  192. 
    
  193. const classComponentUpdater = {
    
  194.   isMounted,
    
  195.   // $FlowFixMe[missing-local-annot]
    
  196.   enqueueSetState(inst: any, payload: any, callback) {
    
  197.     const fiber = getInstance(inst);
    
  198.     const lane = requestUpdateLane(fiber);
    
  199. 
    
  200.     const update = createUpdate(lane);
    
  201.     update.payload = payload;
    
  202.     if (callback !== undefined && callback !== null) {
    
  203.       if (__DEV__) {
    
  204.         warnOnInvalidCallback(callback, 'setState');
    
  205.       }
    
  206.       update.callback = callback;
    
  207.     }
    
  208. 
    
  209.     const root = enqueueUpdate(fiber, update, lane);
    
  210.     if (root !== null) {
    
  211.       scheduleUpdateOnFiber(root, fiber, lane);
    
  212.       entangleTransitions(root, fiber, lane);
    
  213.     }
    
  214. 
    
  215.     if (__DEV__) {
    
  216.       if (enableDebugTracing) {
    
  217.         if (fiber.mode & DebugTracingMode) {
    
  218.           const name = getComponentNameFromFiber(fiber) || 'Unknown';
    
  219.           logStateUpdateScheduled(name, lane, payload);
    
  220.         }
    
  221.       }
    
  222.     }
    
  223. 
    
  224.     if (enableSchedulingProfiler) {
    
  225.       markStateUpdateScheduled(fiber, lane);
    
  226.     }
    
  227.   },
    
  228.   enqueueReplaceState(inst: any, payload: any, callback: null) {
    
  229.     const fiber = getInstance(inst);
    
  230.     const lane = requestUpdateLane(fiber);
    
  231. 
    
  232.     const update = createUpdate(lane);
    
  233.     update.tag = ReplaceState;
    
  234.     update.payload = payload;
    
  235. 
    
  236.     if (callback !== undefined && callback !== null) {
    
  237.       if (__DEV__) {
    
  238.         warnOnInvalidCallback(callback, 'replaceState');
    
  239.       }
    
  240.       update.callback = callback;
    
  241.     }
    
  242. 
    
  243.     const root = enqueueUpdate(fiber, update, lane);
    
  244.     if (root !== null) {
    
  245.       scheduleUpdateOnFiber(root, fiber, lane);
    
  246.       entangleTransitions(root, fiber, lane);
    
  247.     }
    
  248. 
    
  249.     if (__DEV__) {
    
  250.       if (enableDebugTracing) {
    
  251.         if (fiber.mode & DebugTracingMode) {
    
  252.           const name = getComponentNameFromFiber(fiber) || 'Unknown';
    
  253.           logStateUpdateScheduled(name, lane, payload);
    
  254.         }
    
  255.       }
    
  256.     }
    
  257. 
    
  258.     if (enableSchedulingProfiler) {
    
  259.       markStateUpdateScheduled(fiber, lane);
    
  260.     }
    
  261.   },
    
  262.   // $FlowFixMe[missing-local-annot]
    
  263.   enqueueForceUpdate(inst: any, callback) {
    
  264.     const fiber = getInstance(inst);
    
  265.     const lane = requestUpdateLane(fiber);
    
  266. 
    
  267.     const update = createUpdate(lane);
    
  268.     update.tag = ForceUpdate;
    
  269. 
    
  270.     if (callback !== undefined && callback !== null) {
    
  271.       if (__DEV__) {
    
  272.         warnOnInvalidCallback(callback, 'forceUpdate');
    
  273.       }
    
  274.       update.callback = callback;
    
  275.     }
    
  276. 
    
  277.     const root = enqueueUpdate(fiber, update, lane);
    
  278.     if (root !== null) {
    
  279.       scheduleUpdateOnFiber(root, fiber, lane);
    
  280.       entangleTransitions(root, fiber, lane);
    
  281.     }
    
  282. 
    
  283.     if (__DEV__) {
    
  284.       if (enableDebugTracing) {
    
  285.         if (fiber.mode & DebugTracingMode) {
    
  286.           const name = getComponentNameFromFiber(fiber) || 'Unknown';
    
  287.           logForceUpdateScheduled(name, lane);
    
  288.         }
    
  289.       }
    
  290.     }
    
  291. 
    
  292.     if (enableSchedulingProfiler) {
    
  293.       markForceUpdateScheduled(fiber, lane);
    
  294.     }
    
  295.   },
    
  296. };
    
  297. 
    
  298. function checkShouldComponentUpdate(
    
  299.   workInProgress: Fiber,
    
  300.   ctor: any,
    
  301.   oldProps: any,
    
  302.   newProps: any,
    
  303.   oldState: any,
    
  304.   newState: any,
    
  305.   nextContext: any,
    
  306. ) {
    
  307.   const instance = workInProgress.stateNode;
    
  308.   if (typeof instance.shouldComponentUpdate === 'function') {
    
  309.     let shouldUpdate = instance.shouldComponentUpdate(
    
  310.       newProps,
    
  311.       newState,
    
  312.       nextContext,
    
  313.     );
    
  314.     if (__DEV__) {
    
  315.       if (
    
  316.         debugRenderPhaseSideEffectsForStrictMode &&
    
  317.         workInProgress.mode & StrictLegacyMode
    
  318.       ) {
    
  319.         setIsStrictModeForDevtools(true);
    
  320.         try {
    
  321.           // Invoke the function an extra time to help detect side-effects.
    
  322.           shouldUpdate = instance.shouldComponentUpdate(
    
  323.             newProps,
    
  324.             newState,
    
  325.             nextContext,
    
  326.           );
    
  327.         } finally {
    
  328.           setIsStrictModeForDevtools(false);
    
  329.         }
    
  330.       }
    
  331.       if (shouldUpdate === undefined) {
    
  332.         console.error(
    
  333.           '%s.shouldComponentUpdate(): Returned undefined instead of a ' +
    
  334.             'boolean value. Make sure to return true or false.',
    
  335.           getComponentNameFromType(ctor) || 'Component',
    
  336.         );
    
  337.       }
    
  338.     }
    
  339. 
    
  340.     return shouldUpdate;
    
  341.   }
    
  342. 
    
  343.   if (ctor.prototype && ctor.prototype.isPureReactComponent) {
    
  344.     return (
    
  345.       !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
    
  346.     );
    
  347.   }
    
  348. 
    
  349.   return true;
    
  350. }
    
  351. 
    
  352. function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) {
    
  353.   const instance = workInProgress.stateNode;
    
  354.   if (__DEV__) {
    
  355.     const name = getComponentNameFromType(ctor) || 'Component';
    
  356.     const renderPresent = instance.render;
    
  357. 
    
  358.     if (!renderPresent) {
    
  359.       if (ctor.prototype && typeof ctor.prototype.render === 'function') {
    
  360.         console.error(
    
  361.           '%s(...): No `render` method found on the returned component ' +
    
  362.             'instance: did you accidentally return an object from the constructor?',
    
  363.           name,
    
  364.         );
    
  365.       } else {
    
  366.         console.error(
    
  367.           '%s(...): No `render` method found on the returned component ' +
    
  368.             'instance: you may have forgotten to define `render`.',
    
  369.           name,
    
  370.         );
    
  371.       }
    
  372.     }
    
  373. 
    
  374.     if (
    
  375.       instance.getInitialState &&
    
  376.       !instance.getInitialState.isReactClassApproved &&
    
  377.       !instance.state
    
  378.     ) {
    
  379.       console.error(
    
  380.         'getInitialState was defined on %s, a plain JavaScript class. ' +
    
  381.           'This is only supported for classes created using React.createClass. ' +
    
  382.           'Did you mean to define a state property instead?',
    
  383.         name,
    
  384.       );
    
  385.     }
    
  386.     if (
    
  387.       instance.getDefaultProps &&
    
  388.       !instance.getDefaultProps.isReactClassApproved
    
  389.     ) {
    
  390.       console.error(
    
  391.         'getDefaultProps was defined on %s, a plain JavaScript class. ' +
    
  392.           'This is only supported for classes created using React.createClass. ' +
    
  393.           'Use a static property to define defaultProps instead.',
    
  394.         name,
    
  395.       );
    
  396.     }
    
  397.     if (instance.propTypes) {
    
  398.       console.error(
    
  399.         'propTypes was defined as an instance property on %s. Use a static ' +
    
  400.           'property to define propTypes instead.',
    
  401.         name,
    
  402.       );
    
  403.     }
    
  404.     if (instance.contextType) {
    
  405.       console.error(
    
  406.         'contextType was defined as an instance property on %s. Use a static ' +
    
  407.           'property to define contextType instead.',
    
  408.         name,
    
  409.       );
    
  410.     }
    
  411. 
    
  412.     if (disableLegacyContext) {
    
  413.       if (ctor.childContextTypes) {
    
  414.         console.error(
    
  415.           '%s uses the legacy childContextTypes API which is no longer supported. ' +
    
  416.             'Use React.createContext() instead.',
    
  417.           name,
    
  418.         );
    
  419.       }
    
  420.       if (ctor.contextTypes) {
    
  421.         console.error(
    
  422.           '%s uses the legacy contextTypes API which is no longer supported. ' +
    
  423.             'Use React.createContext() with static contextType instead.',
    
  424.           name,
    
  425.         );
    
  426.       }
    
  427.     } else {
    
  428.       if (instance.contextTypes) {
    
  429.         console.error(
    
  430.           'contextTypes was defined as an instance property on %s. Use a static ' +
    
  431.             'property to define contextTypes instead.',
    
  432.           name,
    
  433.         );
    
  434.       }
    
  435. 
    
  436.       if (
    
  437.         ctor.contextType &&
    
  438.         ctor.contextTypes &&
    
  439.         !didWarnAboutContextTypeAndContextTypes.has(ctor)
    
  440.       ) {
    
  441.         didWarnAboutContextTypeAndContextTypes.add(ctor);
    
  442.         console.error(
    
  443.           '%s declares both contextTypes and contextType static properties. ' +
    
  444.             'The legacy contextTypes property will be ignored.',
    
  445.           name,
    
  446.         );
    
  447.       }
    
  448.     }
    
  449. 
    
  450.     if (typeof instance.componentShouldUpdate === 'function') {
    
  451.       console.error(
    
  452.         '%s has a method called ' +
    
  453.           'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
    
  454.           'The name is phrased as a question because the function is ' +
    
  455.           'expected to return a value.',
    
  456.         name,
    
  457.       );
    
  458.     }
    
  459.     if (
    
  460.       ctor.prototype &&
    
  461.       ctor.prototype.isPureReactComponent &&
    
  462.       typeof instance.shouldComponentUpdate !== 'undefined'
    
  463.     ) {
    
  464.       console.error(
    
  465.         '%s has a method called shouldComponentUpdate(). ' +
    
  466.           'shouldComponentUpdate should not be used when extending React.PureComponent. ' +
    
  467.           'Please extend React.Component if shouldComponentUpdate is used.',
    
  468.         getComponentNameFromType(ctor) || 'A pure component',
    
  469.       );
    
  470.     }
    
  471.     if (typeof instance.componentDidUnmount === 'function') {
    
  472.       console.error(
    
  473.         '%s has a method called ' +
    
  474.           'componentDidUnmount(). But there is no such lifecycle method. ' +
    
  475.           'Did you mean componentWillUnmount()?',
    
  476.         name,
    
  477.       );
    
  478.     }
    
  479.     if (typeof instance.componentDidReceiveProps === 'function') {
    
  480.       console.error(
    
  481.         '%s has a method called ' +
    
  482.           'componentDidReceiveProps(). But there is no such lifecycle method. ' +
    
  483.           'If you meant to update the state in response to changing props, ' +
    
  484.           'use componentWillReceiveProps(). If you meant to fetch data or ' +
    
  485.           'run side-effects or mutations after React has updated the UI, use componentDidUpdate().',
    
  486.         name,
    
  487.       );
    
  488.     }
    
  489.     if (typeof instance.componentWillRecieveProps === 'function') {
    
  490.       console.error(
    
  491.         '%s has a method called ' +
    
  492.           'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
    
  493.         name,
    
  494.       );
    
  495.     }
    
  496.     if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
    
  497.       console.error(
    
  498.         '%s has a method called ' +
    
  499.           'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?',
    
  500.         name,
    
  501.       );
    
  502.     }
    
  503.     const hasMutatedProps = instance.props !== newProps;
    
  504.     if (instance.props !== undefined && hasMutatedProps) {
    
  505.       console.error(
    
  506.         '%s(...): When calling super() in `%s`, make sure to pass ' +
    
  507.           "up the same props that your component's constructor was passed.",
    
  508.         name,
    
  509.         name,
    
  510.       );
    
  511.     }
    
  512.     if (instance.defaultProps) {
    
  513.       console.error(
    
  514.         'Setting defaultProps as an instance property on %s is not supported and will be ignored.' +
    
  515.           ' Instead, define defaultProps as a static property on %s.',
    
  516.         name,
    
  517.         name,
    
  518.       );
    
  519.     }
    
  520. 
    
  521.     if (
    
  522.       typeof instance.getSnapshotBeforeUpdate === 'function' &&
    
  523.       typeof instance.componentDidUpdate !== 'function' &&
    
  524.       !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)
    
  525.     ) {
    
  526.       didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
    
  527.       console.error(
    
  528.         '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' +
    
  529.           'This component defines getSnapshotBeforeUpdate() only.',
    
  530.         getComponentNameFromType(ctor),
    
  531.       );
    
  532.     }
    
  533. 
    
  534.     if (typeof instance.getDerivedStateFromProps === 'function') {
    
  535.       console.error(
    
  536.         '%s: getDerivedStateFromProps() is defined as an instance method ' +
    
  537.           'and will be ignored. Instead, declare it as a static method.',
    
  538.         name,
    
  539.       );
    
  540.     }
    
  541.     if (typeof instance.getDerivedStateFromError === 'function') {
    
  542.       console.error(
    
  543.         '%s: getDerivedStateFromError() is defined as an instance method ' +
    
  544.           'and will be ignored. Instead, declare it as a static method.',
    
  545.         name,
    
  546.       );
    
  547.     }
    
  548.     if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
    
  549.       console.error(
    
  550.         '%s: getSnapshotBeforeUpdate() is defined as a static method ' +
    
  551.           'and will be ignored. Instead, declare it as an instance method.',
    
  552.         name,
    
  553.       );
    
  554.     }
    
  555.     const state = instance.state;
    
  556.     if (state && (typeof state !== 'object' || isArray(state))) {
    
  557.       console.error('%s.state: must be set to an object or null', name);
    
  558.     }
    
  559.     if (
    
  560.       typeof instance.getChildContext === 'function' &&
    
  561.       typeof ctor.childContextTypes !== 'object'
    
  562.     ) {
    
  563.       console.error(
    
  564.         '%s.getChildContext(): childContextTypes must be defined in order to ' +
    
  565.           'use getChildContext().',
    
  566.         name,
    
  567.       );
    
  568.     }
    
  569.   }
    
  570. }
    
  571. 
    
  572. function adoptClassInstance(workInProgress: Fiber, instance: any): void {
    
  573.   instance.updater = classComponentUpdater;
    
  574.   workInProgress.stateNode = instance;
    
  575.   // The instance needs access to the fiber so that it can schedule updates
    
  576.   setInstance(instance, workInProgress);
    
  577.   if (__DEV__) {
    
  578.     instance._reactInternalInstance = fakeInternalInstance;
    
  579.   }
    
  580. }
    
  581. 
    
  582. function constructClassInstance(
    
  583.   workInProgress: Fiber,
    
  584.   ctor: any,
    
  585.   props: any,
    
  586. ): any {
    
  587.   let isLegacyContextConsumer = false;
    
  588.   let unmaskedContext = emptyContextObject;
    
  589.   let context = emptyContextObject;
    
  590.   const contextType = ctor.contextType;
    
  591. 
    
  592.   if (__DEV__) {
    
  593.     if ('contextType' in ctor) {
    
  594.       const isValid =
    
  595.         // Allow null for conditional declaration
    
  596.         contextType === null ||
    
  597.         (contextType !== undefined &&
    
  598.           contextType.$$typeof === REACT_CONTEXT_TYPE &&
    
  599.           contextType._context === undefined); // Not a <Context.Consumer>
    
  600. 
    
  601.       if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
    
  602.         didWarnAboutInvalidateContextType.add(ctor);
    
  603. 
    
  604.         let addendum = '';
    
  605.         if (contextType === undefined) {
    
  606.           addendum =
    
  607.             ' However, it is set to undefined. ' +
    
  608.             'This can be caused by a typo or by mixing up named and default imports. ' +
    
  609.             'This can also happen due to a circular dependency, so ' +
    
  610.             'try moving the createContext() call to a separate file.';
    
  611.         } else if (typeof contextType !== 'object') {
    
  612.           addendum = ' However, it is set to a ' + typeof contextType + '.';
    
  613.         } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
    
  614.           addendum = ' Did you accidentally pass the Context.Provider instead?';
    
  615.         } else if (contextType._context !== undefined) {
    
  616.           // <Context.Consumer>
    
  617.           addendum = ' Did you accidentally pass the Context.Consumer instead?';
    
  618.         } else {
    
  619.           addendum =
    
  620.             ' However, it is set to an object with keys {' +
    
  621.             Object.keys(contextType).join(', ') +
    
  622.             '}.';
    
  623.         }
    
  624.         console.error(
    
  625.           '%s defines an invalid contextType. ' +
    
  626.             'contextType should point to the Context object returned by React.createContext().%s',
    
  627.           getComponentNameFromType(ctor) || 'Component',
    
  628.           addendum,
    
  629.         );
    
  630.       }
    
  631.     }
    
  632.   }
    
  633. 
    
  634.   if (typeof contextType === 'object' && contextType !== null) {
    
  635.     context = readContext((contextType: any));
    
  636.   } else if (!disableLegacyContext) {
    
  637.     unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
    
  638.     const contextTypes = ctor.contextTypes;
    
  639.     isLegacyContextConsumer =
    
  640.       contextTypes !== null && contextTypes !== undefined;
    
  641.     context = isLegacyContextConsumer
    
  642.       ? getMaskedContext(workInProgress, unmaskedContext)
    
  643.       : emptyContextObject;
    
  644.   }
    
  645. 
    
  646.   let instance = new ctor(props, context);
    
  647.   // Instantiate twice to help detect side-effects.
    
  648.   if (__DEV__) {
    
  649.     if (
    
  650.       debugRenderPhaseSideEffectsForStrictMode &&
    
  651.       workInProgress.mode & StrictLegacyMode
    
  652.     ) {
    
  653.       setIsStrictModeForDevtools(true);
    
  654.       try {
    
  655.         instance = new ctor(props, context); // eslint-disable-line no-new
    
  656.       } finally {
    
  657.         setIsStrictModeForDevtools(false);
    
  658.       }
    
  659.     }
    
  660.   }
    
  661. 
    
  662.   const state = (workInProgress.memoizedState =
    
  663.     instance.state !== null && instance.state !== undefined
    
  664.       ? instance.state
    
  665.       : null);
    
  666.   adoptClassInstance(workInProgress, instance);
    
  667. 
    
  668.   if (__DEV__) {
    
  669.     if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
    
  670.       const componentName = getComponentNameFromType(ctor) || 'Component';
    
  671.       if (!didWarnAboutUninitializedState.has(componentName)) {
    
  672.         didWarnAboutUninitializedState.add(componentName);
    
  673.         console.error(
    
  674.           '`%s` uses `getDerivedStateFromProps` but its initial state is ' +
    
  675.             '%s. This is not recommended. Instead, define the initial state by ' +
    
  676.             'assigning an object to `this.state` in the constructor of `%s`. ' +
    
  677.             'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.',
    
  678.           componentName,
    
  679.           instance.state === null ? 'null' : 'undefined',
    
  680.           componentName,
    
  681.         );
    
  682.       }
    
  683.     }
    
  684. 
    
  685.     // If new component APIs are defined, "unsafe" lifecycles won't be called.
    
  686.     // Warn about these lifecycles if they are present.
    
  687.     // Don't warn about react-lifecycles-compat polyfilled methods though.
    
  688.     if (
    
  689.       typeof ctor.getDerivedStateFromProps === 'function' ||
    
  690.       typeof instance.getSnapshotBeforeUpdate === 'function'
    
  691.     ) {
    
  692.       let foundWillMountName = null;
    
  693.       let foundWillReceivePropsName = null;
    
  694.       let foundWillUpdateName = null;
    
  695.       if (
    
  696.         typeof instance.componentWillMount === 'function' &&
    
  697.         instance.componentWillMount.__suppressDeprecationWarning !== true
    
  698.       ) {
    
  699.         foundWillMountName = 'componentWillMount';
    
  700.       } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
    
  701.         foundWillMountName = 'UNSAFE_componentWillMount';
    
  702.       }
    
  703.       if (
    
  704.         typeof instance.componentWillReceiveProps === 'function' &&
    
  705.         instance.componentWillReceiveProps.__suppressDeprecationWarning !== true
    
  706.       ) {
    
  707.         foundWillReceivePropsName = 'componentWillReceiveProps';
    
  708.       } else if (
    
  709.         typeof instance.UNSAFE_componentWillReceiveProps === 'function'
    
  710.       ) {
    
  711.         foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
    
  712.       }
    
  713.       if (
    
  714.         typeof instance.componentWillUpdate === 'function' &&
    
  715.         instance.componentWillUpdate.__suppressDeprecationWarning !== true
    
  716.       ) {
    
  717.         foundWillUpdateName = 'componentWillUpdate';
    
  718.       } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
    
  719.         foundWillUpdateName = 'UNSAFE_componentWillUpdate';
    
  720.       }
    
  721.       if (
    
  722.         foundWillMountName !== null ||
    
  723.         foundWillReceivePropsName !== null ||
    
  724.         foundWillUpdateName !== null
    
  725.       ) {
    
  726.         const componentName = getComponentNameFromType(ctor) || 'Component';
    
  727.         const newApiName =
    
  728.           typeof ctor.getDerivedStateFromProps === 'function'
    
  729.             ? 'getDerivedStateFromProps()'
    
  730.             : 'getSnapshotBeforeUpdate()';
    
  731.         if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(componentName)) {
    
  732.           didWarnAboutLegacyLifecyclesAndDerivedState.add(componentName);
    
  733.           console.error(
    
  734.             'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
    
  735.               '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' +
    
  736.               'The above lifecycles should be removed. Learn more about this warning here:\n' +
    
  737.               'https://reactjs.org/link/unsafe-component-lifecycles',
    
  738.             componentName,
    
  739.             newApiName,
    
  740.             foundWillMountName !== null ? `\n  ${foundWillMountName}` : '',
    
  741.             foundWillReceivePropsName !== null
    
  742.               ? `\n  ${foundWillReceivePropsName}`
    
  743.               : '',
    
  744.             foundWillUpdateName !== null ? `\n  ${foundWillUpdateName}` : '',
    
  745.           );
    
  746.         }
    
  747.       }
    
  748.     }
    
  749.   }
    
  750. 
    
  751.   // Cache unmasked context so we can avoid recreating masked context unless necessary.
    
  752.   // ReactFiberContext usually updates this cache but can't for newly-created instances.
    
  753.   if (isLegacyContextConsumer) {
    
  754.     cacheContext(workInProgress, unmaskedContext, context);
    
  755.   }
    
  756. 
    
  757.   return instance;
    
  758. }
    
  759. 
    
  760. function callComponentWillMount(workInProgress: Fiber, instance: any) {
    
  761.   const oldState = instance.state;
    
  762. 
    
  763.   if (typeof instance.componentWillMount === 'function') {
    
  764.     instance.componentWillMount();
    
  765.   }
    
  766.   if (typeof instance.UNSAFE_componentWillMount === 'function') {
    
  767.     instance.UNSAFE_componentWillMount();
    
  768.   }
    
  769. 
    
  770.   if (oldState !== instance.state) {
    
  771.     if (__DEV__) {
    
  772.       console.error(
    
  773.         '%s.componentWillMount(): Assigning directly to this.state is ' +
    
  774.           "deprecated (except inside a component's " +
    
  775.           'constructor). Use setState instead.',
    
  776.         getComponentNameFromFiber(workInProgress) || 'Component',
    
  777.       );
    
  778.     }
    
  779.     classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
    
  780.   }
    
  781. }
    
  782. 
    
  783. function callComponentWillReceiveProps(
    
  784.   workInProgress: Fiber,
    
  785.   instance: any,
    
  786.   newProps: any,
    
  787.   nextContext: any,
    
  788. ) {
    
  789.   const oldState = instance.state;
    
  790.   if (typeof instance.componentWillReceiveProps === 'function') {
    
  791.     instance.componentWillReceiveProps(newProps, nextContext);
    
  792.   }
    
  793.   if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
    
  794.     instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
    
  795.   }
    
  796. 
    
  797.   if (instance.state !== oldState) {
    
  798.     if (__DEV__) {
    
  799.       const componentName =
    
  800.         getComponentNameFromFiber(workInProgress) || 'Component';
    
  801.       if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
    
  802.         didWarnAboutStateAssignmentForComponent.add(componentName);
    
  803.         console.error(
    
  804.           '%s.componentWillReceiveProps(): Assigning directly to ' +
    
  805.             "this.state is deprecated (except inside a component's " +
    
  806.             'constructor). Use setState instead.',
    
  807.           componentName,
    
  808.         );
    
  809.       }
    
  810.     }
    
  811.     classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
    
  812.   }
    
  813. }
    
  814. 
    
  815. // Invokes the mount life-cycles on a previously never rendered instance.
    
  816. function mountClassInstance(
    
  817.   workInProgress: Fiber,
    
  818.   ctor: any,
    
  819.   newProps: any,
    
  820.   renderLanes: Lanes,
    
  821. ): void {
    
  822.   if (__DEV__) {
    
  823.     checkClassInstance(workInProgress, ctor, newProps);
    
  824.   }
    
  825. 
    
  826.   const instance = workInProgress.stateNode;
    
  827.   instance.props = newProps;
    
  828.   instance.state = workInProgress.memoizedState;
    
  829.   instance.refs = {};
    
  830. 
    
  831.   initializeUpdateQueue(workInProgress);
    
  832. 
    
  833.   const contextType = ctor.contextType;
    
  834.   if (typeof contextType === 'object' && contextType !== null) {
    
  835.     instance.context = readContext(contextType);
    
  836.   } else if (disableLegacyContext) {
    
  837.     instance.context = emptyContextObject;
    
  838.   } else {
    
  839.     const unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
    
  840.     instance.context = getMaskedContext(workInProgress, unmaskedContext);
    
  841.   }
    
  842. 
    
  843.   if (__DEV__) {
    
  844.     if (instance.state === newProps) {
    
  845.       const componentName = getComponentNameFromType(ctor) || 'Component';
    
  846.       if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
    
  847.         didWarnAboutDirectlyAssigningPropsToState.add(componentName);
    
  848.         console.error(
    
  849.           '%s: It is not recommended to assign props directly to state ' +
    
  850.             "because updates to props won't be reflected in state. " +
    
  851.             'In most cases, it is better to use props directly.',
    
  852.           componentName,
    
  853.         );
    
  854.       }
    
  855.     }
    
  856. 
    
  857.     if (workInProgress.mode & StrictLegacyMode) {
    
  858.       ReactStrictModeWarnings.recordLegacyContextWarning(
    
  859.         workInProgress,
    
  860.         instance,
    
  861.       );
    
  862.     }
    
  863. 
    
  864.     ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(
    
  865.       workInProgress,
    
  866.       instance,
    
  867.     );
    
  868.   }
    
  869. 
    
  870.   instance.state = workInProgress.memoizedState;
    
  871. 
    
  872.   const getDerivedStateFromProps = ctor.getDerivedStateFromProps;
    
  873.   if (typeof getDerivedStateFromProps === 'function') {
    
  874.     applyDerivedStateFromProps(
    
  875.       workInProgress,
    
  876.       ctor,
    
  877.       getDerivedStateFromProps,
    
  878.       newProps,
    
  879.     );
    
  880.     instance.state = workInProgress.memoizedState;
    
  881.   }
    
  882. 
    
  883.   // In order to support react-lifecycles-compat polyfilled components,
    
  884.   // Unsafe lifecycles should not be invoked for components using the new APIs.
    
  885.   if (
    
  886.     typeof ctor.getDerivedStateFromProps !== 'function' &&
    
  887.     typeof instance.getSnapshotBeforeUpdate !== 'function' &&
    
  888.     (typeof instance.UNSAFE_componentWillMount === 'function' ||
    
  889.       typeof instance.componentWillMount === 'function')
    
  890.   ) {
    
  891.     callComponentWillMount(workInProgress, instance);
    
  892.     // If we had additional state updates during this life-cycle, let's
    
  893.     // process them now.
    
  894.     processUpdateQueue(workInProgress, newProps, instance, renderLanes);
    
  895.     instance.state = workInProgress.memoizedState;
    
  896.   }
    
  897. 
    
  898.   if (typeof instance.componentDidMount === 'function') {
    
  899.     workInProgress.flags |= Update | LayoutStatic;
    
  900.   }
    
  901.   if (__DEV__ && (workInProgress.mode & StrictEffectsMode) !== NoMode) {
    
  902.     workInProgress.flags |= MountLayoutDev;
    
  903.   }
    
  904. }
    
  905. 
    
  906. function resumeMountClassInstance(
    
  907.   workInProgress: Fiber,
    
  908.   ctor: any,
    
  909.   newProps: any,
    
  910.   renderLanes: Lanes,
    
  911. ): boolean {
    
  912.   const instance = workInProgress.stateNode;
    
  913. 
    
  914.   const oldProps = workInProgress.memoizedProps;
    
  915.   instance.props = oldProps;
    
  916. 
    
  917.   const oldContext = instance.context;
    
  918.   const contextType = ctor.contextType;
    
  919.   let nextContext = emptyContextObject;
    
  920.   if (typeof contextType === 'object' && contextType !== null) {
    
  921.     nextContext = readContext(contextType);
    
  922.   } else if (!disableLegacyContext) {
    
  923.     const nextLegacyUnmaskedContext = getUnmaskedContext(
    
  924.       workInProgress,
    
  925.       ctor,
    
  926.       true,
    
  927.     );
    
  928.     nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
    
  929.   }
    
  930. 
    
  931.   const getDerivedStateFromProps = ctor.getDerivedStateFromProps;
    
  932.   const hasNewLifecycles =
    
  933.     typeof getDerivedStateFromProps === 'function' ||
    
  934.     typeof instance.getSnapshotBeforeUpdate === 'function';
    
  935. 
    
  936.   // Note: During these life-cycles, instance.props/instance.state are what
    
  937.   // ever the previously attempted to render - not the "current". However,
    
  938.   // during componentDidUpdate we pass the "current" props.
    
  939. 
    
  940.   // In order to support react-lifecycles-compat polyfilled components,
    
  941.   // Unsafe lifecycles should not be invoked for components using the new APIs.
    
  942.   if (
    
  943.     !hasNewLifecycles &&
    
  944.     (typeof instance.UNSAFE_componentWillReceiveProps === 'function' ||
    
  945.       typeof instance.componentWillReceiveProps === 'function')
    
  946.   ) {
    
  947.     if (oldProps !== newProps || oldContext !== nextContext) {
    
  948.       callComponentWillReceiveProps(
    
  949.         workInProgress,
    
  950.         instance,
    
  951.         newProps,
    
  952.         nextContext,
    
  953.       );
    
  954.     }
    
  955.   }
    
  956. 
    
  957.   resetHasForceUpdateBeforeProcessing();
    
  958. 
    
  959.   const oldState = workInProgress.memoizedState;
    
  960.   let newState = (instance.state = oldState);
    
  961.   processUpdateQueue(workInProgress, newProps, instance, renderLanes);
    
  962.   newState = workInProgress.memoizedState;
    
  963.   if (
    
  964.     oldProps === newProps &&
    
  965.     oldState === newState &&
    
  966.     !hasContextChanged() &&
    
  967.     !checkHasForceUpdateAfterProcessing()
    
  968.   ) {
    
  969.     // If an update was already in progress, we should schedule an Update
    
  970.     // effect even though we're bailing out, so that cWU/cDU are called.
    
  971.     if (typeof instance.componentDidMount === 'function') {
    
  972.       workInProgress.flags |= Update | LayoutStatic;
    
  973.     }
    
  974.     if (__DEV__ && (workInProgress.mode & StrictEffectsMode) !== NoMode) {
    
  975.       workInProgress.flags |= MountLayoutDev;
    
  976.     }
    
  977.     return false;
    
  978.   }
    
  979. 
    
  980.   if (typeof getDerivedStateFromProps === 'function') {
    
  981.     applyDerivedStateFromProps(
    
  982.       workInProgress,
    
  983.       ctor,
    
  984.       getDerivedStateFromProps,
    
  985.       newProps,
    
  986.     );
    
  987.     newState = workInProgress.memoizedState;
    
  988.   }
    
  989. 
    
  990.   const shouldUpdate =
    
  991.     checkHasForceUpdateAfterProcessing() ||
    
  992.     checkShouldComponentUpdate(
    
  993.       workInProgress,
    
  994.       ctor,
    
  995.       oldProps,
    
  996.       newProps,
    
  997.       oldState,
    
  998.       newState,
    
  999.       nextContext,
    
  1000.     );
    
  1001. 
    
  1002.   if (shouldUpdate) {
    
  1003.     // In order to support react-lifecycles-compat polyfilled components,
    
  1004.     // Unsafe lifecycles should not be invoked for components using the new APIs.
    
  1005.     if (
    
  1006.       !hasNewLifecycles &&
    
  1007.       (typeof instance.UNSAFE_componentWillMount === 'function' ||
    
  1008.         typeof instance.componentWillMount === 'function')
    
  1009.     ) {
    
  1010.       if (typeof instance.componentWillMount === 'function') {
    
  1011.         instance.componentWillMount();
    
  1012.       }
    
  1013.       if (typeof instance.UNSAFE_componentWillMount === 'function') {
    
  1014.         instance.UNSAFE_componentWillMount();
    
  1015.       }
    
  1016.     }
    
  1017.     if (typeof instance.componentDidMount === 'function') {
    
  1018.       workInProgress.flags |= Update | LayoutStatic;
    
  1019.     }
    
  1020.     if (__DEV__ && (workInProgress.mode & StrictEffectsMode) !== NoMode) {
    
  1021.       workInProgress.flags |= MountLayoutDev;
    
  1022.     }
    
  1023.   } else {
    
  1024.     // If an update was already in progress, we should schedule an Update
    
  1025.     // effect even though we're bailing out, so that cWU/cDU are called.
    
  1026.     if (typeof instance.componentDidMount === 'function') {
    
  1027.       workInProgress.flags |= Update | LayoutStatic;
    
  1028.     }
    
  1029.     if (__DEV__ && (workInProgress.mode & StrictEffectsMode) !== NoMode) {
    
  1030.       workInProgress.flags |= MountLayoutDev;
    
  1031.     }
    
  1032. 
    
  1033.     // If shouldComponentUpdate returned false, we should still update the
    
  1034.     // memoized state to indicate that this work can be reused.
    
  1035.     workInProgress.memoizedProps = newProps;
    
  1036.     workInProgress.memoizedState = newState;
    
  1037.   }
    
  1038. 
    
  1039.   // Update the existing instance's state, props, and context pointers even
    
  1040.   // if shouldComponentUpdate returns false.
    
  1041.   instance.props = newProps;
    
  1042.   instance.state = newState;
    
  1043.   instance.context = nextContext;
    
  1044. 
    
  1045.   return shouldUpdate;
    
  1046. }
    
  1047. 
    
  1048. // Invokes the update life-cycles and returns false if it shouldn't rerender.
    
  1049. function updateClassInstance(
    
  1050.   current: Fiber,
    
  1051.   workInProgress: Fiber,
    
  1052.   ctor: any,
    
  1053.   newProps: any,
    
  1054.   renderLanes: Lanes,
    
  1055. ): boolean {
    
  1056.   const instance = workInProgress.stateNode;
    
  1057. 
    
  1058.   cloneUpdateQueue(current, workInProgress);
    
  1059. 
    
  1060.   const unresolvedOldProps = workInProgress.memoizedProps;
    
  1061.   const oldProps =
    
  1062.     workInProgress.type === workInProgress.elementType
    
  1063.       ? unresolvedOldProps
    
  1064.       : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
    
  1065.   instance.props = oldProps;
    
  1066.   const unresolvedNewProps = workInProgress.pendingProps;
    
  1067. 
    
  1068.   const oldContext = instance.context;
    
  1069.   const contextType = ctor.contextType;
    
  1070.   let nextContext = emptyContextObject;
    
  1071.   if (typeof contextType === 'object' && contextType !== null) {
    
  1072.     nextContext = readContext(contextType);
    
  1073.   } else if (!disableLegacyContext) {
    
  1074.     const nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
    
  1075.     nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
    
  1076.   }
    
  1077. 
    
  1078.   const getDerivedStateFromProps = ctor.getDerivedStateFromProps;
    
  1079.   const hasNewLifecycles =
    
  1080.     typeof getDerivedStateFromProps === 'function' ||
    
  1081.     typeof instance.getSnapshotBeforeUpdate === 'function';
    
  1082. 
    
  1083.   // Note: During these life-cycles, instance.props/instance.state are what
    
  1084.   // ever the previously attempted to render - not the "current". However,
    
  1085.   // during componentDidUpdate we pass the "current" props.
    
  1086. 
    
  1087.   // In order to support react-lifecycles-compat polyfilled components,
    
  1088.   // Unsafe lifecycles should not be invoked for components using the new APIs.
    
  1089.   if (
    
  1090.     !hasNewLifecycles &&
    
  1091.     (typeof instance.UNSAFE_componentWillReceiveProps === 'function' ||
    
  1092.       typeof instance.componentWillReceiveProps === 'function')
    
  1093.   ) {
    
  1094.     if (
    
  1095.       unresolvedOldProps !== unresolvedNewProps ||
    
  1096.       oldContext !== nextContext
    
  1097.     ) {
    
  1098.       callComponentWillReceiveProps(
    
  1099.         workInProgress,
    
  1100.         instance,
    
  1101.         newProps,
    
  1102.         nextContext,
    
  1103.       );
    
  1104.     }
    
  1105.   }
    
  1106. 
    
  1107.   resetHasForceUpdateBeforeProcessing();
    
  1108. 
    
  1109.   const oldState = workInProgress.memoizedState;
    
  1110.   let newState = (instance.state = oldState);
    
  1111.   processUpdateQueue(workInProgress, newProps, instance, renderLanes);
    
  1112.   newState = workInProgress.memoizedState;
    
  1113. 
    
  1114.   if (
    
  1115.     unresolvedOldProps === unresolvedNewProps &&
    
  1116.     oldState === newState &&
    
  1117.     !hasContextChanged() &&
    
  1118.     !checkHasForceUpdateAfterProcessing() &&
    
  1119.     !(
    
  1120.       enableLazyContextPropagation &&
    
  1121.       current !== null &&
    
  1122.       current.dependencies !== null &&
    
  1123.       checkIfContextChanged(current.dependencies)
    
  1124.     )
    
  1125.   ) {
    
  1126.     // If an update was already in progress, we should schedule an Update
    
  1127.     // effect even though we're bailing out, so that cWU/cDU are called.
    
  1128.     if (typeof instance.componentDidUpdate === 'function') {
    
  1129.       if (
    
  1130.         unresolvedOldProps !== current.memoizedProps ||
    
  1131.         oldState !== current.memoizedState
    
  1132.       ) {
    
  1133.         workInProgress.flags |= Update;
    
  1134.       }
    
  1135.     }
    
  1136.     if (typeof instance.getSnapshotBeforeUpdate === 'function') {
    
  1137.       if (
    
  1138.         unresolvedOldProps !== current.memoizedProps ||
    
  1139.         oldState !== current.memoizedState
    
  1140.       ) {
    
  1141.         workInProgress.flags |= Snapshot;
    
  1142.       }
    
  1143.     }
    
  1144.     return false;
    
  1145.   }
    
  1146. 
    
  1147.   if (typeof getDerivedStateFromProps === 'function') {
    
  1148.     applyDerivedStateFromProps(
    
  1149.       workInProgress,
    
  1150.       ctor,
    
  1151.       getDerivedStateFromProps,
    
  1152.       newProps,
    
  1153.     );
    
  1154.     newState = workInProgress.memoizedState;
    
  1155.   }
    
  1156. 
    
  1157.   const shouldUpdate =
    
  1158.     checkHasForceUpdateAfterProcessing() ||
    
  1159.     checkShouldComponentUpdate(
    
  1160.       workInProgress,
    
  1161.       ctor,
    
  1162.       oldProps,
    
  1163.       newProps,
    
  1164.       oldState,
    
  1165.       newState,
    
  1166.       nextContext,
    
  1167.     ) ||
    
  1168.     // TODO: In some cases, we'll end up checking if context has changed twice,
    
  1169.     // both before and after `shouldComponentUpdate` has been called. Not ideal,
    
  1170.     // but I'm loath to refactor this function. This only happens for memoized
    
  1171.     // components so it's not that common.
    
  1172.     (enableLazyContextPropagation &&
    
  1173.       current !== null &&
    
  1174.       current.dependencies !== null &&
    
  1175.       checkIfContextChanged(current.dependencies));
    
  1176. 
    
  1177.   if (shouldUpdate) {
    
  1178.     // In order to support react-lifecycles-compat polyfilled components,
    
  1179.     // Unsafe lifecycles should not be invoked for components using the new APIs.
    
  1180.     if (
    
  1181.       !hasNewLifecycles &&
    
  1182.       (typeof instance.UNSAFE_componentWillUpdate === 'function' ||
    
  1183.         typeof instance.componentWillUpdate === 'function')
    
  1184.     ) {
    
  1185.       if (typeof instance.componentWillUpdate === 'function') {
    
  1186.         instance.componentWillUpdate(newProps, newState, nextContext);
    
  1187.       }
    
  1188.       if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
    
  1189.         instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
    
  1190.       }
    
  1191.     }
    
  1192.     if (typeof instance.componentDidUpdate === 'function') {
    
  1193.       workInProgress.flags |= Update;
    
  1194.     }
    
  1195.     if (typeof instance.getSnapshotBeforeUpdate === 'function') {
    
  1196.       workInProgress.flags |= Snapshot;
    
  1197.     }
    
  1198.   } else {
    
  1199.     // If an update was already in progress, we should schedule an Update
    
  1200.     // effect even though we're bailing out, so that cWU/cDU are called.
    
  1201.     if (typeof instance.componentDidUpdate === 'function') {
    
  1202.       if (
    
  1203.         unresolvedOldProps !== current.memoizedProps ||
    
  1204.         oldState !== current.memoizedState
    
  1205.       ) {
    
  1206.         workInProgress.flags |= Update;
    
  1207.       }
    
  1208.     }
    
  1209.     if (typeof instance.getSnapshotBeforeUpdate === 'function') {
    
  1210.       if (
    
  1211.         unresolvedOldProps !== current.memoizedProps ||
    
  1212.         oldState !== current.memoizedState
    
  1213.       ) {
    
  1214.         workInProgress.flags |= Snapshot;
    
  1215.       }
    
  1216.     }
    
  1217. 
    
  1218.     // If shouldComponentUpdate returned false, we should still update the
    
  1219.     // memoized props/state to indicate that this work can be reused.
    
  1220.     workInProgress.memoizedProps = newProps;
    
  1221.     workInProgress.memoizedState = newState;
    
  1222.   }
    
  1223. 
    
  1224.   // Update the existing instance's state, props, and context pointers even
    
  1225.   // if shouldComponentUpdate returns false.
    
  1226.   instance.props = newProps;
    
  1227.   instance.state = newState;
    
  1228.   instance.context = nextContext;
    
  1229. 
    
  1230.   return shouldUpdate;
    
  1231. }
    
  1232. 
    
  1233. export {
    
  1234.   adoptClassInstance,
    
  1235.   constructClassInstance,
    
  1236.   mountClassInstance,
    
  1237.   resumeMountClassInstance,
    
  1238.   updateClassInstance,
    
  1239. };