How to use mountOpaqueIdentifier method in Playwright Internal

Best JavaScript code snippet using playwright-internal

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

ReactFiberHooks.old.js

Source: ReactFiberHooks.old.js Github

copy
1/**
2 * Copyright (c) Facebook, Inc. and its 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 *      
8 */
9
10             
11                
12                             
13                           
14               
15                           
16                                                            
17                                                  
18                                                     
19                                                             
20                                                    
21                                                         
22
23import ReactSharedInternals from 'shared/ReactSharedInternals';
24import {
25  enableDebugTracing,
26  enableSchedulingProfiler,
27  enableNewReconciler,
28  decoupleUpdatePriorityFromScheduler,
29} from 'shared/ReactFeatureFlags';
30
31import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
32import {
33  NoLane,
34  NoLanes,
35  InputContinuousLanePriority,
36  isSubsetOfLanes,
37  mergeLanes,
38  removeLanes,
39  markRootEntangled,
40  markRootMutableRead,
41  getCurrentUpdateLanePriority,
42  setCurrentUpdateLanePriority,
43  higherLanePriority,
44  DefaultLanePriority,
45} from './ReactFiberLane';
46import {readContext} from './ReactFiberNewContext.old';
47import {
48  Update as UpdateEffect,
49  Passive as PassiveEffect,
50} from './ReactFiberFlags';
51import {
52  HasEffect as HookHasEffect,
53  Layout as HookLayout,
54  Passive as HookPassive,
55} from './ReactHookEffectTags';
56import {
57  getWorkInProgressRoot,
58  scheduleUpdateOnFiber,
59  requestUpdateLane,
60  requestEventTime,
61  warnIfNotCurrentlyActingEffectsInDEV,
62  warnIfNotCurrentlyActingUpdatesInDev,
63  warnIfNotScopedWithMatchingAct,
64  markSkippedUpdateLanes,
65} from './ReactFiberWorkLoop.old';
66
67import invariant from 'shared/invariant';
68import getComponentName from 'shared/getComponentName';
69import is from 'shared/objectIs';
70import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork.old';
71import {
72  UserBlockingPriority,
73  NormalPriority,
74  runWithPriority,
75  getCurrentPriorityLevel,
76} from './SchedulerWithReactIntegration.old';
77import {getIsHydrating} from './ReactFiberHydrationContext.old';
78import {
79  makeClientId,
80  makeClientIdInDEV,
81  makeOpaqueHydratingObject,
82} from './ReactFiberHostConfig';
83import {
84  getWorkInProgressVersion,
85  markSourceAsDirty,
86  setWorkInProgressVersion,
87  warnAboutMultipleRenderersDEV,
88} from './ReactMutableSource.old';
89import {getIsRendering} from './ReactCurrentFiber';
90import {logStateUpdateScheduled} from './DebugTracing';
91import {markStateUpdateScheduled} from './SchedulingProfiler';
92
93const {ReactCurrentDispatcher, ReactCurrentBatchConfig} = ReactSharedInternals;
94
95                      
96             
97            
98                                     
99                       
100                     
101                                
102   
103
104                           
105                               
106                                
107                                            
108                              
109   
110
111                      
112              
113                
114                
115            
116               
117                     
118                 
119             
120                         
121                   
122                      
123                   
124                      
125                          
126
127let didWarnAboutMismatchedHooksForComponent;
128let didWarnAboutUseOpaqueIdentifier;
129if (__DEV__) {
130  didWarnAboutUseOpaqueIdentifier = {};
131  didWarnAboutMismatchedHooksForComponent = new Set();
132}
133
134                     
135                     
136                 
137                                     
138                                      
139                    
140   
141
142                       
143                 
144                                    
145                               
146                            
147               
148   
149
150                                                                         
151
152                                        
153
154                             
155
156// These are set right before calling the component.
157let renderLanes        = NoLanes;
158// The work-in-progress fiber. I've named it differently to distinguish it from
159// the work-in-progress hook.
160let currentlyRenderingFiber        = (null     );
161
162// Hooks are stored as a linked list on the fiber's memoizedState field. The
163// current hook list is the list that belongs to the current fiber. The
164// work-in-progress hook list is a new list that will be added to the
165// work-in-progress fiber.
166let currentHook              = null;
167let workInProgressHook              = null;
168
169// Whether an update was scheduled at any point during the render phase. This
170// does not get reset if we do another render pass; only when we're completely
171// finished evaluating this component. This is an optimization so we know
172// whether we need to clear render phase updates after a throw.
173let didScheduleRenderPhaseUpdate          = false;
174// Where an update was scheduled only during the current render pass. This
175// gets reset after each attempt.
176// TODO: Maybe there's some way to consolidate this with
177// `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
178let didScheduleRenderPhaseUpdateDuringThisPass          = false;
179
180const RE_RENDER_LIMIT = 25;
181
182// In DEV, this is the name of the currently executing primitive hook
183let currentHookNameInDev            = null;
184
185// In DEV, this list ensures that hooks are called in the same order between renders.
186// The list stores the order of hooks used during the initial render (mount).
187// Subsequent renders (updates) reference this list.
188let hookTypesDev                         = null;
189let hookTypesUpdateIndexDev         = -1;
190
191// In DEV, this tracks whether currently rendering component needs to ignore
192// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
193// When true, such Hooks will always be "remounted". Only used during hot reload.
194let ignorePreviousDependencies          = false;
195
196function mountHookTypesDev() {
197  if (__DEV__) {
198    const hookName = ((currentHookNameInDev     )          );
199
200    if (hookTypesDev === null) {
201      hookTypesDev = [hookName];
202    } else {
203      hookTypesDev.push(hookName);
204    }
205  }
206}
207
208function updateHookTypesDev() {
209  if (__DEV__) {
210    const hookName = ((currentHookNameInDev     )          );
211
212    if (hookTypesDev !== null) {
213      hookTypesUpdateIndexDev++;
214      if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
215        warnOnHookMismatchInDev(hookName);
216      }
217    }
218  }
219}
220
221function checkDepsAreArrayDev(deps       ) {
222  if (__DEV__) {
223    if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
224      // Verify deps, but only on mount to avoid extra checks.
225      // It's unlikely their type would change as usually you define them inline.
226      console.error(
227        '%s received a final argument that is not an array (instead, received `%s`). When ' +
228          'specified, the final argument must be an array.',
229        currentHookNameInDev,
230        typeof deps,
231      );
232    }
233  }
234}
235
236function warnOnHookMismatchInDev(currentHookName          ) {
237  if (__DEV__) {
238    const componentName = getComponentName(currentlyRenderingFiber.type);
239    if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
240      didWarnAboutMismatchedHooksForComponent.add(componentName);
241
242      if (hookTypesDev !== null) {
243        let table = '';
244
245        const secondColumnStart = 30;
246
247        for (let i = 0; i <= ((hookTypesUpdateIndexDev     )        ); i++) {
248          const oldHookName = hookTypesDev[i];
249          const newHookName =
250            i === ((hookTypesUpdateIndexDev     )        )
251              ? currentHookName
252              : oldHookName;
253
254          let row = `${i + 1}. ${oldHookName}`;
255
256          // Extra space so second column lines up
257          // lol @ IE not supporting String#repeat
258          while (row.length < secondColumnStart) {
259            row += ' ';
260          }
261
262          row += newHookName + '\n';
263
264          table += row;
265        }
266
267        console.error(
268          'React has detected a change in the order of Hooks called by %s. ' +
269            'This will lead to bugs and errors if not fixed. ' +
270            'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' +
271            '   Previous render            Next render\n' +
272            '   ------------------------------------------------------\n' +
273            '%s' +
274            '   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',
275          componentName,
276          table,
277        );
278      }
279    }
280  }
281}
282
283function throwInvalidHookError() {
284  invariant(
285    false,
286    'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
287      ' one of the following reasons:\n' +
288      '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
289      '2. You might be breaking the Rules of Hooks\n' +
290      '3. You might have more than one copy of React in the same app\n' +
291      'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
292  );
293}
294
295function areHookInputsEqual(
296  nextDeps              ,
297  prevDeps                     ,
298) {
299  if (__DEV__) {
300    if (ignorePreviousDependencies) {
301      // Only true when this component is being hot reloaded.
302      return false;
303    }
304  }
305
306  if (prevDeps === null) {
307    if (__DEV__) {
308      console.error(
309        '%s received a final argument during this render, but not during ' +
310          'the previous render. Even though the final argument is optional, ' +
311          'its type cannot change between renders.',
312        currentHookNameInDev,
313      );
314    }
315    return false;
316  }
317
318  if (__DEV__) {
319    // Don't bother comparing lengths in prod because these arrays should be
320    // passed inline.
321    if (nextDeps.length !== prevDeps.length) {
322      console.error(
323        'The final argument passed to %s changed size between renders. The ' +
324          'order and size of this array must remain constant.\n\n' +
325          'Previous: %s\n' +
326          'Incoming: %s',
327        currentHookNameInDev,
328        `[${prevDeps.join(', ')}]`,
329        `[${nextDeps.join(', ')}]`,
330      );
331    }
332  }
333  for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
334    if (is(nextDeps[i], prevDeps[i])) {
335      continue;
336    }
337    return false;
338  }
339  return true;
340}
341
342export function renderWithHooks                  (
343  current              ,
344  workInProgress       ,
345  Component                                   ,
346  props       ,
347  secondArg           ,
348  nextRenderLanes       ,
349)      {
350  renderLanes = nextRenderLanes;
351  currentlyRenderingFiber = workInProgress;
352
353  if (__DEV__) {
354    hookTypesDev =
355      current !== null
356        ? ((current._debugHookTypes     )                 )
357        : null;
358    hookTypesUpdateIndexDev = -1;
359    // Used for hot reloading:
360    ignorePreviousDependencies =
361      current !== null && current.type !== workInProgress.type;
362  }
363
364  workInProgress.memoizedState = null;
365  workInProgress.updateQueue = null;
366  workInProgress.lanes = NoLanes;
367
368  // The following should have already been reset
369  // currentHook = null;
370  // workInProgressHook = null;
371
372  // didScheduleRenderPhaseUpdate = false;
373
374  // TODO Warn if no hooks are used at all during mount, then some are used during update.
375  // Currently we will identify the update render as a mount because memoizedState === null.
376  // This is tricky because it's valid for certain types of components (e.g. React.lazy)
377
378  // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
379  // Non-stateful hooks (e.g. context) don't get added to memoizedState,
380  // so memoizedState would be null during updates and mounts.
381  if (__DEV__) {
382    if (current !== null && current.memoizedState !== null) {
383      ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
384    } else if (hookTypesDev !== null) {
385      // This dispatcher handles an edge case where a component is updating,
386      // but no stateful hooks have been used.
387      // We want to match the production code behavior (which will use HooksDispatcherOnMount),
388      // but with the extra DEV validation to ensure hooks ordering hasn't changed.
389      // This dispatcher does that.
390      ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
391    } else {
392      ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
393    }
394  } else {
395    ReactCurrentDispatcher.current =
396      current === null || current.memoizedState === null
397        ? HooksDispatcherOnMount
398        : HooksDispatcherOnUpdate;
399  }
400
401  let children = Component(props, secondArg);
402
403  // Check if there was a render phase update
404  if (didScheduleRenderPhaseUpdateDuringThisPass) {
405    // Keep rendering in a loop for as long as render phase updates continue to
406    // be scheduled. Use a counter to prevent infinite loops.
407    let numberOfReRenders         = 0;
408    do {
409      didScheduleRenderPhaseUpdateDuringThisPass = false;
410      invariant(
411        numberOfReRenders < RE_RENDER_LIMIT,
412        'Too many re-renders. React limits the number of renders to prevent ' +
413          'an infinite loop.',
414      );
415
416      numberOfReRenders += 1;
417      if (__DEV__) {
418        // Even when hot reloading, allow dependencies to stabilize
419        // after first render to prevent infinite render phase updates.
420        ignorePreviousDependencies = false;
421      }
422
423      // Start over from the beginning of the list
424      currentHook = null;
425      workInProgressHook = null;
426
427      workInProgress.updateQueue = null;
428
429      if (__DEV__) {
430        // Also validate hook order for cascading updates.
431        hookTypesUpdateIndexDev = -1;
432      }
433
434      ReactCurrentDispatcher.current = __DEV__
435        ? HooksDispatcherOnRerenderInDEV
436        : HooksDispatcherOnRerender;
437
438      children = Component(props, secondArg);
439    } while (didScheduleRenderPhaseUpdateDuringThisPass);
440  }
441
442  // We can assume the previous dispatcher is always this one, since we set it
443  // at the beginning of the render phase and there's no re-entrancy.
444  ReactCurrentDispatcher.current = ContextOnlyDispatcher;
445
446  if (__DEV__) {
447    workInProgress._debugHookTypes = hookTypesDev;
448  }
449
450  // This check uses currentHook so that it works the same in DEV and prod bundles.
451  // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
452  const didRenderTooFewHooks =
453    currentHook !== null && currentHook.next !== null;
454
455  renderLanes = NoLanes;
456  currentlyRenderingFiber = (null     );
457
458  currentHook = null;
459  workInProgressHook = null;
460
461  if (__DEV__) {
462    currentHookNameInDev = null;
463    hookTypesDev = null;
464    hookTypesUpdateIndexDev = -1;
465  }
466
467  didScheduleRenderPhaseUpdate = false;
468
469  invariant(
470    !didRenderTooFewHooks,
471    'Rendered fewer hooks than expected. This may be caused by an accidental ' +
472      'early return statement.',
473  );
474
475  return children;
476}
477
478export function bailoutHooks(
479  current       ,
480  workInProgress       ,
481  lanes       ,
482) {
483  workInProgress.updateQueue = current.updateQueue;
484  workInProgress.flags &= ~(PassiveEffect | UpdateEffect);
485  current.lanes = removeLanes(current.lanes, lanes);
486}
487
488export function resetHooksAfterThrow()       {
489  // We can assume the previous dispatcher is always this one, since we set it
490  // at the beginning of the render phase and there's no re-entrancy.
491  ReactCurrentDispatcher.current = ContextOnlyDispatcher;
492
493  if (didScheduleRenderPhaseUpdate) {
494    // There were render phase updates. These are only valid for this render
495    // phase, which we are now aborting. Remove the updates from the queues so
496    // they do not persist to the next render. Do not remove updates from hooks
497    // that weren't processed.
498    //
499    // Only reset the updates from the queue if it has a clone. If it does
500    // not have a clone, that means it wasn't processed, and the updates were
501    // scheduled before we entered the render phase.
502    let hook              = currentlyRenderingFiber.memoizedState;
503    while (hook !== null) {
504      const queue = hook.queue;
505      if (queue !== null) {
506        queue.pending = null;
507      }
508      hook = hook.next;
509    }
510    didScheduleRenderPhaseUpdate = false;
511  }
512
513  renderLanes = NoLanes;
514  currentlyRenderingFiber = (null     );
515
516  currentHook = null;
517  workInProgressHook = null;
518
519  if (__DEV__) {
520    hookTypesDev = null;
521    hookTypesUpdateIndexDev = -1;
522
523    currentHookNameInDev = null;
524
525    isUpdatingOpaqueValueInRenderPhase = false;
526  }
527
528  didScheduleRenderPhaseUpdateDuringThisPass = false;
529}
530
531function mountWorkInProgressHook()       {
532  const hook       = {
533    memoizedState: null,
534
535    baseState: null,
536    baseQueue: null,
537    queue: null,
538
539    next: null,
540  };
541
542  if (workInProgressHook === null) {
543    // This is the first hook in the list
544    currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
545  } else {
546    // Append to the end of the list
547    workInProgressHook = workInProgressHook.next = hook;
548  }
549  return workInProgressHook;
550}
551
552function updateWorkInProgressHook()       {
553  // This function is used both for updates and for re-renders triggered by a
554  // render phase update. It assumes there is either a current hook we can
555  // clone, or a work-in-progress hook from a previous render pass that we can
556  // use as a base. When we reach the end of the base list, we must switch to
557  // the dispatcher used for mounts.
558  let nextCurrentHook             ;
559  if (currentHook === null) {
560    const current = currentlyRenderingFiber.alternate;
561    if (current !== null) {
562      nextCurrentHook = current.memoizedState;
563    } else {
564      nextCurrentHook = null;
565    }
566  } else {
567    nextCurrentHook = currentHook.next;
568  }
569
570  let nextWorkInProgressHook             ;
571  if (workInProgressHook === null) {
572    nextWorkInProgressHook = currentlyRenderingFiber.memoizedState;
573  } else {
574    nextWorkInProgressHook = workInProgressHook.next;
575  }
576
577  if (nextWorkInProgressHook !== null) {
578    // There's already a work-in-progress. Reuse it.
579    workInProgressHook = nextWorkInProgressHook;
580    nextWorkInProgressHook = workInProgressHook.next;
581
582    currentHook = nextCurrentHook;
583  } else {
584    // Clone from the current hook.
585
586    invariant(
587      nextCurrentHook !== null,
588      'Rendered more hooks than during the previous render.',
589    );
590    currentHook = nextCurrentHook;
591
592    const newHook       = {
593      memoizedState: currentHook.memoizedState,
594
595      baseState: currentHook.baseState,
596      baseQueue: currentHook.baseQueue,
597      queue: currentHook.queue,
598
599      next: null,
600    };
601
602    if (workInProgressHook === null) {
603      // This is the first hook in the list.
604      currentlyRenderingFiber.memoizedState = workInProgressHook = newHook;
605    } else {
606      // Append to the end of the list.
607      workInProgressHook = workInProgressHook.next = newHook;
608    }
609  }
610  return workInProgressHook;
611}
612
613function createFunctionComponentUpdateQueue()                               {
614  return {
615    lastEffect: null,
616  };
617}
618
619function basicStateReducer   (state   , action                     )    {
620  // $FlowFixMe: Flow doesn't like mixed types
621  return typeof action === 'function' ? action(state) : action;
622}
623
624function mountReducer         (
625  reducer             ,
626  initialArg   ,
627  init         ,
628)                   {
629  const hook = mountWorkInProgressHook();
630  let initialState;
631  if (init !== undefined) {
632    initialState = init(initialArg);
633  } else {
634    initialState = ((initialArg     )   );
635  }
636  hook.memoizedState = hook.baseState = initialState;
637  const queue = (hook.queue = {
638    pending: null,
639    dispatch: null,
640    lastRenderedReducer: reducer,
641    lastRenderedState: (initialState     ),
642  });
643  const dispatch              = (queue.dispatch = (dispatchAction.bind(
644    null,
645    currentlyRenderingFiber,
646    queue,
647  )     ));
648  return [hook.memoizedState, dispatch];
649}
650
651function updateReducer         (
652  reducer             ,
653  initialArg   ,
654  init         ,
655)                   {
656  const hook = updateWorkInProgressHook();
657  const queue = hook.queue;
658  invariant(
659    queue !== null,
660    'Should have a queue. This is likely a bug in React. Please file an issue.',
661  );
662
663  queue.lastRenderedReducer = reducer;
664
665  const current       = (currentHook     );
666
667  // The last rebase update that is NOT part of the base state.
668  let baseQueue = current.baseQueue;
669
670  // The last pending update that hasn't been processed yet.
671  const pendingQueue = queue.pending;
672  if (pendingQueue !== null) {
673    // We have new updates that haven't been processed yet.
674    // We'll add them to the base queue.
675    if (baseQueue !== null) {
676      // Merge the pending queue and the base queue.
677      const baseFirst = baseQueue.next;
678      const pendingFirst = pendingQueue.next;
679      baseQueue.next = pendingFirst;
680      pendingQueue.next = baseFirst;
681    }
682    if (__DEV__) {
683      if (current.baseQueue !== baseQueue) {
684        // Internal invariant that should never happen, but feasibly could in
685        // the future if we implement resuming, or some form of that.
686        console.error(
687          'Internal error: Expected work-in-progress queue to be a clone. ' +
688            'This is a bug in React.',
689        );
690      }
691    }
692    current.baseQueue = baseQueue = pendingQueue;
693    queue.pending = null;
694  }
695
696  if (baseQueue !== null) {
697    // We have a queue to process.
698    const first = baseQueue.next;
699    let newState = current.baseState;
700
701    let newBaseState = null;
702    let newBaseQueueFirst = null;
703    let newBaseQueueLast = null;
704    let update = first;
705    do {
706      const updateLane = update.lane;
707      if (!isSubsetOfLanes(renderLanes, updateLane)) {
708        // Priority is insufficient. Skip this update. If this is the first
709        // skipped update, the previous update/state is the new base
710        // update/state.
711        const clone               = {
712          lane: updateLane,
713          action: update.action,
714          eagerReducer: update.eagerReducer,
715          eagerState: update.eagerState,
716          next: (null     ),
717        };
718        if (newBaseQueueLast === null) {
719          newBaseQueueFirst = newBaseQueueLast = clone;
720          newBaseState = newState;
721        } else {
722          newBaseQueueLast = newBaseQueueLast.next = clone;
723        }
724        // Update the remaining priority in the queue.
725        // TODO: Don't need to accumulate this. Instead, we can remove
726        // renderLanes from the original lanes.
727        currentlyRenderingFiber.lanes = mergeLanes(
728          currentlyRenderingFiber.lanes,
729          updateLane,
730        );
731        markSkippedUpdateLanes(updateLane);
732      } else {
733        // This update does have sufficient priority.
734
735        if (newBaseQueueLast !== null) {
736          const clone               = {
737            // This update is going to be committed so we never want uncommit
738            // it. Using NoLane works because 0 is a subset of all bitmasks, so
739            // this will never be skipped by the check above.
740            lane: NoLane,
741            action: update.action,
742            eagerReducer: update.eagerReducer,
743            eagerState: update.eagerState,
744            next: (null     ),
745          };
746          newBaseQueueLast = newBaseQueueLast.next = clone;
747        }
748
749        // Process this update.
750        if (update.eagerReducer === reducer) {
751          // If this update was processed eagerly, and its reducer matches the
752          // current reducer, we can use the eagerly computed state.
753          newState = ((update.eagerState     )   );
754        } else {
755          const action = update.action;
756          newState = reducer(newState, action);
757        }
758      }
759      update = update.next;
760    } while (update !== null && update !== first);
761
762    if (newBaseQueueLast === null) {
763      newBaseState = newState;
764    } else {
765      newBaseQueueLast.next = (newBaseQueueFirst     );
766    }
767
768    // Mark that the fiber performed work, but only if the new state is
769    // different from the current state.
770    if (!is(newState, hook.memoizedState)) {
771      markWorkInProgressReceivedUpdate();
772    }
773
774    hook.memoizedState = newState;
775    hook.baseState = newBaseState;
776    hook.baseQueue = newBaseQueueLast;
777
778    queue.lastRenderedState = newState;
779  }
780
781  const dispatch              = (queue.dispatch     );
782  return [hook.memoizedState, dispatch];
783}
784
785function rerenderReducer         (
786  reducer             ,
787  initialArg   ,
788  init         ,
789)                   {
790  const hook = updateWorkInProgressHook();
791  const queue = hook.queue;
792  invariant(
793    queue !== null,
794    'Should have a queue. This is likely a bug in React. Please file an issue.',
795  );
796
797  queue.lastRenderedReducer = reducer;
798
799  // This is a re-render. Apply the new render phase updates to the previous
800  // work-in-progress hook.
801  const dispatch              = (queue.dispatch     );
802  const lastRenderPhaseUpdate = queue.pending;
803  let newState = hook.memoizedState;
804  if (lastRenderPhaseUpdate !== null) {
805    // The queue doesn't persist past this render pass.
806    queue.pending = null;
807
808    const firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
809    let update = firstRenderPhaseUpdate;
810    do {
811      // Process this render phase update. We don't have to check the
812      // priority because it will always be the same as the current
813      // render's.
814      const action = update.action;
815      newState = reducer(newState, action);
816      update = update.next;
817    } while (update !== firstRenderPhaseUpdate);
818
819    // Mark that the fiber performed work, but only if the new state is
820    // different from the current state.
821    if (!is(newState, hook.memoizedState)) {
822      markWorkInProgressReceivedUpdate();
823    }
824
825    hook.memoizedState = newState;
826    // Don't persist the state accumulated from the render phase updates to
827    // the base state unless the queue is empty.
828    // TODO: Not sure if this is the desired semantics, but it's what we
829    // do for gDSFP. I can't remember why.
830    if (hook.baseQueue === null) {
831      hook.baseState = newState;
832    }
833
834    queue.lastRenderedState = newState;
835  }
836  return [newState, dispatch];
837}
838
839                                                      
840         
841                                                              
842                                  
843    
844                             
845                                                        
846   
847
848function readFromUnsubcribedMutableSource                  (
849  root           ,
850  source                       ,
851  getSnapshot                                              ,
852)           {
853  if (__DEV__) {
854    warnAboutMultipleRenderersDEV(source);
855  }
856
857  const getVersion = source._getVersion;
858  const version = getVersion(source._source);
859
860  // Is it safe for this component to read from this source during the current render?
861  let isSafeToReadFromSource = false;
862
863  // Check the version first.
864  // If this render has already been started with a specific version,
865  // we can use it alone to determine if we can safely read from the source.
866  const currentRenderVersion = getWorkInProgressVersion(source);
867  if (currentRenderVersion !== null) {
868    // It's safe to read if the store hasn't been mutated since the last time
869    // we read something.
870    isSafeToReadFromSource = currentRenderVersion === version;
871  } else {
872    // If there's no version, then this is the first time we've read from the
873    // source during the current render pass, so we need to do a bit more work.
874    // What we need to determine is if there are any hooks that already
875    // subscribed to the source, and if so, whether there are any pending
876    // mutations that haven't been synchronized yet.
877    //
878    // If there are no pending mutations, then `root.mutableReadLanes` will be
879    // empty, and we know we can safely read.
880    //
881    // If there *are* pending mutations, we may still be able to safely read
882    // if the currently rendering lanes are inclusive of the pending mutation
883    // lanes, since that guarantees that the value we're about to read from
884    // the source is consistent with the values that we read during the most
885    // recent mutation.
886    isSafeToReadFromSource = isSubsetOfLanes(
887      renderLanes,
888      root.mutableReadLanes,
889    );
890
891    if (isSafeToReadFromSource) {
892      // If it's safe to read from this source during the current render,
893      // store the version in case other components read from it.
894      // A changed version number will let those components know to throw and restart the render.
895      setWorkInProgressVersion(source, version);
896    }
897  }
898
899  if (isSafeToReadFromSource) {
900    const snapshot = getSnapshot(source._source);
901    if (__DEV__) {
902      if (typeof snapshot === 'function') {
903        console.error(
904          'Mutable source should not return a function as the snapshot value. ' +
905            'Functions may close over mutable values and cause tearing.',
906        );
907      }
908    }
909    return snapshot;
910  } else {
911    // This handles the special case of a mutable source being shared between renderers.
912    // In that case, if the source is mutated between the first and second renderer,
913    // The second renderer don't know that it needs to reset the WIP version during unwind,
914    // (because the hook only marks sources as dirty if it's written to their WIP version).
915    // That would cause this tear check to throw again and eventually be visible to the user.
916    // We can avoid this infinite loop by explicitly marking the source as dirty.
917    //
918    // This can lead to tearing in the first renderer when it resumes,
919    // but there's nothing we can do about that (short of throwing here and refusing to continue the render).
920    markSourceAsDirty(source);
921
922    invariant(
923      false,
924      'Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue.',
925    );
926  }
927}
928
929function useMutableSource                  (
930  hook      ,
931  source                       ,
932  getSnapshot                                              ,
933  subscribe                                            ,
934)           {
935  const root = ((getWorkInProgressRoot()     )           );
936  invariant(
937    root !== null,
938    'Expected a work-in-progress root. This is a bug in React. Please file an issue.',
939  );
940
941  const getVersion = source._getVersion;
942  const version = getVersion(source._source);
943
944  const dispatcher = ReactCurrentDispatcher.current;
945
946  // eslint-disable-next-line prefer-const
947  let [currentSnapshot, setSnapshot] = dispatcher.useState(() =>
948    readFromUnsubcribedMutableSource(root, source, getSnapshot),
949  );
950  let snapshot = currentSnapshot;
951
952  // Grab a handle to the state hook as well.
953  // We use it to clear the pending update queue if we have a new source.
954  const stateHook = ((workInProgressHook     )      );
955
956  const memoizedState = ((hook.memoizedState     )                             
957           
958             
959   );
960  const refs = memoizedState.refs;
961  const prevGetSnapshot = refs.getSnapshot;
962  const prevSource = memoizedState.source;
963  const prevSubscribe = memoizedState.subscribe;
964
965  const fiber = currentlyRenderingFiber;
966
967  hook.memoizedState = ({
968    refs,
969    source,
970    subscribe,
971  }                                              );
972
973  // Sync the values needed by our subscription handler after each commit.
974  dispatcher.useEffect(() => {
975    refs.getSnapshot = getSnapshot;
976
977    // Normally the dispatch function for a state hook never changes,
978    // but this hook recreates the queue in certain cases  to avoid updates from stale sources.
979    // handleChange() below needs to reference the dispatch function without re-subscribing,
980    // so we use a ref to ensure that it always has the latest version.
981    refs.setSnapshot = setSnapshot;
982
983    // Check for a possible change between when we last rendered now.
984    const maybeNewVersion = getVersion(source._source);
985    if (!is(version, maybeNewVersion)) {
986      const maybeNewSnapshot = getSnapshot(source._source);
987      if (__DEV__) {
988        if (typeof maybeNewSnapshot === 'function') {
989          console.error(
990            'Mutable source should not return a function as the snapshot value. ' +
991              'Functions may close over mutable values and cause tearing.',
992          );
993        }
994      }
995
996      if (!is(snapshot, maybeNewSnapshot)) {
997        setSnapshot(maybeNewSnapshot);
998
999        const lane = requestUpdateLane(fiber);
1000        markRootMutableRead(root, lane);
1001      }
1002      // If the source mutated between render and now,
1003      // there may be state updates already scheduled from the old source.
1004      // Entangle the updates so that they render in the same batch.
1005      markRootEntangled(root, root.mutableReadLanes);
1006    }
1007  }, [getSnapshot, source, subscribe]);
1008
1009  // If we got a new source or subscribe function, re-subscribe in a passive effect.
1010  dispatcher.useEffect(() => {
1011    const handleChange = () => {
1012      const latestGetSnapshot = refs.getSnapshot;
1013      const latestSetSnapshot = refs.setSnapshot;
1014
1015      try {
1016        latestSetSnapshot(latestGetSnapshot(source._source));
1017
1018        // Record a pending mutable source update with the same expiration time.
1019        const lane = requestUpdateLane(fiber);
1020
1021        markRootMutableRead(root, lane);
1022      } catch (error) {
1023        // A selector might throw after a source mutation.
1024        // e.g. it might try to read from a part of the store that no longer exists.
1025        // In this case we should still schedule an update with React.
1026        // Worst case the selector will throw again and then an error boundary will handle it.
1027        latestSetSnapshot(
1028          (() => {
1029            throw error;
1030          }     ),
1031        );
1032      }
1033    };
1034
1035    const unsubscribe = subscribe(source._source, handleChange);
1036    if (__DEV__) {
1037      if (typeof unsubscribe !== 'function') {
1038        console.error(
1039          'Mutable source subscribe function must return an unsubscribe function.',
1040        );
1041      }
1042    }
1043
1044    return unsubscribe;
1045  }, [source, subscribe]);
1046
1047  // If any of the inputs to useMutableSource change, reading is potentially unsafe.
1048  //
1049  // If either the source or the subscription have changed we can't can't trust the update queue.
1050  // Maybe the source changed in a way that the old subscription ignored but the new one depends on.
1051  //
1052  // If the getSnapshot function changed, we also shouldn't rely on the update queue.
1053  // It's possible that the underlying source was mutated between the when the last "change" event fired,
1054  // and when the current render (with the new getSnapshot function) is processed.
1055  //
1056  // In both cases, we need to throw away pending updates (since they are no longer relevant)
1057  // and treat reading from the source as we do in the mount case.
1058  if (
1059    !is(prevGetSnapshot, getSnapshot) ||
1060    !is(prevSource, source) ||
1061    !is(prevSubscribe, subscribe)
1062  ) {
1063    // Create a new queue and setState method,
1064    // So if there are interleaved updates, they get pushed to the older queue.
1065    // When this becomes current, the previous queue and dispatch method will be discarded,
1066    // including any interleaving updates that occur.
1067    const newQueue = {
1068      pending: null,
1069      dispatch: null,
1070      lastRenderedReducer: basicStateReducer,
1071      lastRenderedState: snapshot,
1072    };
1073    newQueue.dispatch = setSnapshot = (dispatchAction.bind(
1074      null,
1075      currentlyRenderingFiber,
1076      newQueue,
1077    )     );
1078    stateHook.queue = newQueue;
1079    stateHook.baseQueue = null;
1080    snapshot = readFromUnsubcribedMutableSource(root, source, getSnapshot);
1081    stateHook.memoizedState = stateHook.baseState = snapshot;
1082  }
1083
1084  return snapshot;
1085}
1086
1087function mountMutableSource                  (
1088  source                       ,
1089  getSnapshot                                              ,
1090  subscribe                                            ,
1091)           {
1092  const hook = mountWorkInProgressHook();
1093  hook.memoizedState = ({
1094    refs: {
1095      getSnapshot,
1096      setSnapshot: (null     ),
1097    },
1098    source,
1099    subscribe,
1100  }                                              );
1101  return useMutableSource(hook, source, getSnapshot, subscribe);
1102}
1103
1104function updateMutableSource                  (
1105  source                       ,
1106  getSnapshot                                              ,
1107  subscribe                                            ,
1108)           {
1109  const hook = updateWorkInProgressHook();
1110  return useMutableSource(hook, source, getSnapshot, subscribe);
1111}
1112
1113function mountState   (
1114  initialState               ,
1115)                                     {
1116  const hook = mountWorkInProgressHook();
1117  if (typeof initialState === 'function') {
1118    // $FlowFixMe: Flow doesn't like mixed types
1119    initialState = initialState();
1120  }
1121  hook.memoizedState = hook.baseState = initialState;
1122  const queue = (hook.queue = {
1123    pending: null,
1124    dispatch: null,
1125    lastRenderedReducer: basicStateReducer,
1126    lastRenderedState: (initialState     ),
1127  });
1128  const dispatch           
1129                        
1130    = (queue.dispatch = (dispatchAction.bind(
1131    null,
1132    currentlyRenderingFiber,
1133    queue,
1134  )     ));
1135  return [hook.memoizedState, dispatch];
1136}
1137
1138function updateState   (
1139  initialState               ,
1140)                                     {
1141  return updateReducer(basicStateReducer, (initialState     ));
1142}
1143
1144function rerenderState   (
1145  initialState               ,
1146)                                     {
1147  return rerenderReducer(basicStateReducer, (initialState     ));
1148}
1149
1150function pushEffect(tag, create, destroy, deps) {
1151  const effect         = {
1152    tag,
1153    create,
1154    destroy,
1155    deps,
1156    // Circular
1157    next: (null     ),
1158  };
1159  let componentUpdateQueue                                      = (currentlyRenderingFiber.updateQueue     );
1160  if (componentUpdateQueue === null) {
1161    componentUpdateQueue = createFunctionComponentUpdateQueue();
1162    currentlyRenderingFiber.updateQueue = (componentUpdateQueue     );
1163    componentUpdateQueue.lastEffect = effect.next = effect;
1164  } else {
1165    const lastEffect = componentUpdateQueue.lastEffect;
1166    if (lastEffect === null) {
1167      componentUpdateQueue.lastEffect = effect.next = effect;
1168    } else {
1169      const firstEffect = lastEffect.next;
1170      lastEffect.next = effect;
1171      effect.next = firstEffect;
1172      componentUpdateQueue.lastEffect = effect;
1173    }
1174  }
1175  return effect;
1176}
1177
1178function mountRef   (initialValue   )                 {
1179  const hook = mountWorkInProgressHook();
1180  const ref = {current: initialValue};
1181  if (__DEV__) {
1182    Object.seal(ref);
1183  }
1184  hook.memoizedState = ref;
1185  return ref;
1186}
1187
1188function updateRef   (initialValue   )                 {
1189  const hook = updateWorkInProgressHook();
1190  return hook.memoizedState;
1191}
1192
1193function mountEffectImpl(fiberFlags, hookFlags, create, deps)       {
1194  const hook = mountWorkInProgressHook();
1195  const nextDeps = deps === undefined ? null : deps;
1196  currentlyRenderingFiber.flags |= fiberFlags;
1197  hook.memoizedState = pushEffect(
1198    HookHasEffect | hookFlags,
1199    create,
1200    undefined,
1201    nextDeps,
1202  );
1203}
1204
1205function updateEffectImpl(fiberFlags, hookFlags, create, deps)       {
1206  const hook = updateWorkInProgressHook();
1207  const nextDeps = deps === undefined ? null : deps;
1208  let destroy = undefined;
1209
1210  if (currentHook !== null) {
1211    const prevEffect = currentHook.memoizedState;
1212    destroy = prevEffect.destroy;
1213    if (nextDeps !== null) {
1214      const prevDeps = prevEffect.deps;
1215      if (areHookInputsEqual(nextDeps, prevDeps)) {
1216        pushEffect(hookFlags, create, destroy, nextDeps);
1217        return;
1218      }
1219    }
1220  }
1221
1222  currentlyRenderingFiber.flags |= fiberFlags;
1223
1224  hook.memoizedState = pushEffect(
1225    HookHasEffect | hookFlags,
1226    create,
1227    destroy,
1228    nextDeps,
1229  );
1230}
1231
1232function mountEffect(
1233  create                           ,
1234  deps                            ,
1235)       {
1236  if (__DEV__) {
1237    // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
1238    if ('undefined' !== typeof jest) {
1239      warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber);
1240    }
1241  }
1242  return mountEffectImpl(
1243    UpdateEffect | PassiveEffect,
1244    HookPassive,
1245    create,
1246    deps,
1247  );
1248}
1249
1250function updateEffect(
1251  create                           ,
1252  deps                            ,
1253)       {
1254  if (__DEV__) {
1255    // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
1256    if ('undefined' !== typeof jest) {
1257      warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber);
1258    }
1259  }
1260  return updateEffectImpl(
1261    UpdateEffect | PassiveEffect,
1262    HookPassive,
1263    create,
1264    deps,
1265  );
1266}
1267
1268function mountLayoutEffect(
1269  create                           ,
1270  deps                            ,
1271)       {
1272  return mountEffectImpl(UpdateEffect, HookLayout, create, deps);
1273}
1274
1275function updateLayoutEffect(
1276  create                           ,
1277  deps                            ,
1278)       {
1279  return updateEffectImpl(UpdateEffect, HookLayout, create, deps);
1280}
1281
1282function imperativeHandleEffect   (
1283  create         ,
1284  ref                                                                   ,
1285) {
1286  if (typeof ref === 'function') {
1287    const refCallback = ref;
1288    const inst = create();
1289    refCallback(inst);
1290    return () => {
1291      refCallback(null);
1292    };
1293  } else if (ref !== null && ref !== undefined) {
1294    const refObject = ref;
1295    if (__DEV__) {
1296      if (!refObject.hasOwnProperty('current')) {
1297        console.error(
1298          'Expected useImperativeHandle() first argument to either be a ' +
1299            'ref callback or React.createRef() object. Instead received: %s.',
1300          'an object with keys {' + Object.keys(refObject).join(', ') + '}',
1301        );
1302      }
1303    }
1304    const inst = create();
1305    refObject.current = inst;
1306    return () => {
1307      refObject.current = null;
1308    };
1309  }
1310}
1311
1312function mountImperativeHandle   (
1313  ref                                                                   ,
1314  create         ,
1315  deps                            ,
1316)       {
1317  if (__DEV__) {
1318    if (typeof create !== 'function') {
1319      console.error(
1320        'Expected useImperativeHandle() second argument to be a function ' +
1321          'that creates a handle. Instead received: %s.',
1322        create !== null ? typeof create : 'null',
1323      );
1324    }
1325  }
1326
1327  // TODO: If deps are provided, should we skip comparing the ref itself?
1328  const effectDeps =
1329    deps !== null && deps !== undefined ? deps.concat([ref]) : null;
1330
1331  return mountEffectImpl(
1332    UpdateEffect,
1333    HookLayout,
1334    imperativeHandleEffect.bind(null, create, ref),
1335    effectDeps,
1336  );
1337}
1338
1339function updateImperativeHandle   (
1340  ref                                                                   ,
1341  create         ,
1342  deps                            ,
1343)       {
1344  if (__DEV__) {
1345    if (typeof create !== 'function') {
1346      console.error(
1347        'Expected useImperativeHandle() second argument to be a function ' +
1348          'that creates a handle. Instead received: %s.',
1349        create !== null ? typeof create : 'null',
1350      );
1351    }
1352  }
1353
1354  // TODO: If deps are provided, should we skip comparing the ref itself?
1355  const effectDeps =
1356    deps !== null && deps !== undefined ? deps.concat([ref]) : null;
1357
1358  return updateEffectImpl(
1359    UpdateEffect,
1360    HookLayout,
1361    imperativeHandleEffect.bind(null, create, ref),
1362    effectDeps,
1363  );
1364}
1365
1366function mountDebugValue   (value   , formatterFn                      )       {
1367  // This hook is normally a no-op.
1368  // The react-debug-hooks package injects its own implementation
1369  // so that e.g. DevTools can display custom hook values.
1370}
1371
1372const updateDebugValue = mountDebugValue;
1373
1374function mountCallback   (callback   , deps                            )    {
1375  const hook = mountWorkInProgressHook();
1376  const nextDeps = deps === undefined ? null : deps;
1377  hook.memoizedState = [callback, nextDeps];
1378  return callback;
1379}
1380
1381function updateCallback   (callback   , deps                            )    {
1382  const hook = updateWorkInProgressHook();
1383  const nextDeps = deps === undefined ? null : deps;
1384  const prevState = hook.memoizedState;
1385  if (prevState !== null) {
1386    if (nextDeps !== null) {
1387      const prevDeps                      = prevState[1];
1388      if (areHookInputsEqual(nextDeps, prevDeps)) {
1389        return prevState[0];
1390      }
1391    }
1392  }
1393  hook.memoizedState = [callback, nextDeps];
1394  return callback;
1395}
1396
1397function mountMemo   (
1398  nextCreate         ,
1399  deps                            ,
1400)    {
1401  const hook = mountWorkInProgressHook();
1402  const nextDeps = deps === undefined ? null : deps;
1403  const nextValue = nextCreate();
1404  hook.memoizedState = [nextValue, nextDeps];
1405  return nextValue;
1406}
1407
1408function updateMemo   (
1409  nextCreate         ,
1410  deps                            ,
1411)    {
1412  const hook = updateWorkInProgressHook();
1413  const nextDeps = deps === undefined ? null : deps;
1414  const prevState = hook.memoizedState;
1415  if (prevState !== null) {
1416    // Assume these are defined. If they're not, areHookInputsEqual will warn.
1417    if (nextDeps !== null) {
1418      const prevDeps                      = prevState[1];
1419      if (areHookInputsEqual(nextDeps, prevDeps)) {
1420        return prevState[0];
1421      }
1422    }
1423  }
1424  const nextValue = nextCreate();
1425  hook.memoizedState = [nextValue, nextDeps];
1426  return nextValue;
1427}
1428
1429function mountDeferredValue   (value   )    {
1430  const [prevValue, setValue] = mountState(value);
1431  mountEffect(() => {
1432    const prevTransition = ReactCurrentBatchConfig.transition;
1433    ReactCurrentBatchConfig.transition = 1;
1434    try {
1435      setValue(value);
1436    } finally {
1437      ReactCurrentBatchConfig.transition = prevTransition;
1438    }
1439  }, [value]);
1440  return prevValue;
1441}
1442
1443function updateDeferredValue   (value   )    {
1444  const [prevValue, setValue] = updateState(value);
1445  updateEffect(() => {
1446    const prevTransition = ReactCurrentBatchConfig.transition;
1447    ReactCurrentBatchConfig.transition = 1;
1448    try {
1449      setValue(value);
1450    } finally {
1451      ReactCurrentBatchConfig.transition = prevTransition;
1452    }
1453  }, [value]);
1454  return prevValue;
1455}
1456
1457function rerenderDeferredValue   (value   )    {
1458  const [prevValue, setValue] = rerenderState(value);
1459  updateEffect(() => {
1460    const prevTransition = ReactCurrentBatchConfig.transition;
1461    ReactCurrentBatchConfig.transition = 1;
1462    try {
1463      setValue(value);
1464    } finally {
1465      ReactCurrentBatchConfig.transition = prevTransition;
1466    }
1467  }, [value]);
1468  return prevValue;
1469}
1470
1471function startTransition(setPending, callback) {
1472  const priorityLevel = getCurrentPriorityLevel();
1473  if (decoupleUpdatePriorityFromScheduler) {
1474    const previousLanePriority = getCurrentUpdateLanePriority();
1475    setCurrentUpdateLanePriority(
1476      higherLanePriority(previousLanePriority, InputContinuousLanePriority),
1477    );
1478
1479    runWithPriority(
1480      priorityLevel < UserBlockingPriority
1481        ? UserBlockingPriority
1482        : priorityLevel,
1483      () => {
1484        setPending(true);
1485      },
1486    );
1487
1488    // TODO: Can remove this. Was only necessary because we used to give
1489    // different behavior to transitions without a config object. Now they are
1490    // all treated the same.
1491    setCurrentUpdateLanePriority(DefaultLanePriority);
1492
1493    runWithPriority(
1494      priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
1495      () => {
1496        const prevTransition = ReactCurrentBatchConfig.transition;
1497        ReactCurrentBatchConfig.transition = 1;
1498        try {
1499          setPending(false);
1500          callback();
1501        } finally {
1502          if (decoupleUpdatePriorityFromScheduler) {
1503            setCurrentUpdateLanePriority(previousLanePriority);
1504          }
1505          ReactCurrentBatchConfig.transition = prevTransition;
1506        }
1507      },
1508    );
1509  } else {
1510    runWithPriority(
1511      priorityLevel < UserBlockingPriority
1512        ? UserBlockingPriority
1513        : priorityLevel,
1514      () => {
1515        setPending(true);
1516      },
1517    );
1518
1519    runWithPriority(
1520      priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
1521      () => {
1522        const prevTransition = ReactCurrentBatchConfig.transition;
1523        ReactCurrentBatchConfig.transition = 1;
1524        try {
1525          setPending(false);
1526          callback();
1527        } finally {
1528          ReactCurrentBatchConfig.transition = prevTransition;
1529        }
1530      },
1531    );
1532  }
1533}
1534
1535function mountTransition()                                  {
1536  const [isPending, setPending] = mountState(false);
1537  // The `start` method can be stored on a ref, since `setPending`
1538  // never changes.
1539  const start = startTransition.bind(null, setPending);
1540  mountRef(start);
1541  return [start, isPending];
1542}
1543
1544function updateTransition()                                  {
1545  const [isPending] = updateState(false);
1546  const startRef = updateRef();
1547  const start                       = (startRef.current     );
1548  return [start, isPending];
1549}
1550
1551function rerenderTransition()                                  {
1552  const [isPending] = rerenderState(false);
1553  const startRef = updateRef();
1554  const start                       = (startRef.current     );
1555  return [start, isPending];
1556}
1557
1558let isUpdatingOpaqueValueInRenderPhase = false;
1559export function getIsUpdatingOpaqueValueInRenderPhaseInDEV()                 {
1560  if (__DEV__) {
1561    return isUpdatingOpaqueValueInRenderPhase;
1562  }
1563}
1564
1565function warnOnOpaqueIdentifierAccessInDEV(fiber) {
1566  if (__DEV__) {
1567    // TODO: Should warn in effects and callbacks, too
1568    const name = getComponentName(fiber.type) || 'Unknown';
1569    if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) {
1570      console.error(
1571        'The object passed back from useOpaqueIdentifier is meant to be ' +
1572          'passed through to attributes only. Do not read the ' +
1573          'value directly.',
1574      );
1575      didWarnAboutUseOpaqueIdentifier[name] = true;
1576    }
1577  }
1578}
1579
1580function mountOpaqueIdentifier()                      {
1581  const makeId = __DEV__
1582    ? makeClientIdInDEV.bind(
1583        null,
1584        warnOnOpaqueIdentifierAccessInDEV.bind(null, currentlyRenderingFiber),
1585      )
1586    : makeClientId;
1587
1588  if (getIsHydrating()) {
1589    let didUpgrade = false;
1590    const fiber = currentlyRenderingFiber;
1591    const readValue = () => {
1592      if (!didUpgrade) {
1593        // Only upgrade once. This works even inside the render phase because
1594        // the update is added to a shared queue, which outlasts the
1595        // in-progress render.
1596        didUpgrade = true;
1597        if (__DEV__) {
1598          isUpdatingOpaqueValueInRenderPhase = true;
1599          setId(makeId());
1600          isUpdatingOpaqueValueInRenderPhase = false;
1601          warnOnOpaqueIdentifierAccessInDEV(fiber);
1602        } else {
1603          setId(makeId());
1604        }
1605      }
1606      invariant(
1607        false,
1608        'The object passed back from useOpaqueIdentifier is meant to be ' +
1609          'passed through to attributes only. Do not read the value directly.',
1610      );
1611    };
1612    const id = makeOpaqueHydratingObject(readValue);
1613
1614    const setId = mountState(id)[1];
1615
1616    if ((currentlyRenderingFiber.mode & BlockingMode) === NoMode) {
1617      currentlyRenderingFiber.flags |= UpdateEffect | PassiveEffect;
1618      pushEffect(
1619        HookHasEffect | HookPassive,
1620        () => {
1621          setId(makeId());
1622        },
1623        undefined,
1624        null,
1625      );
1626    }
1627    return id;
1628  } else {
1629    const id = makeId();
1630    mountState(id);
1631    return id;
1632  }
1633}
1634
1635function updateOpaqueIdentifier()                      {
1636  const id = updateState(undefined)[0];
1637  return id;
1638}
1639
1640function rerenderOpaqueIdentifier()                      {
1641  const id = rerenderState(undefined)[0];
1642  return id;
1643}
1644
1645function dispatchAction      (
1646  fiber       ,
1647  queue                   ,
1648  action   ,
1649) {
1650  if (__DEV__) {
1651    if (typeof arguments[3] === 'function') {
1652      console.error(
1653        "State updates from the useState() and useReducer() Hooks don't support the " +
1654          'second callback argument. To execute a side effect after ' +
1655          'rendering, declare it in the component body with useEffect().',
1656      );
1657    }
1658  }
1659
1660  const eventTime = requestEventTime();
1661  const lane = requestUpdateLane(fiber);
1662
1663  const update               = {
1664    lane,
1665    action,
1666    eagerReducer: null,
1667    eagerState: null,
1668    next: (null     ),
1669  };
1670
1671  // Append the update to the end of the list.
1672  const pending = queue.pending;
1673  if (pending === null) {
1674    // This is the first update. Create a circular list.
1675    update.next = update;
1676  } else {
1677    update.next = pending.next;
1678    pending.next = update;
1679  }
1680  queue.pending = update;
1681
1682  const alternate = fiber.alternate;
1683  if (
1684    fiber === currentlyRenderingFiber ||
1685    (alternate !== null && alternate === currentlyRenderingFiber)
1686  ) {
1687    // This is a render phase update. Stash it in a lazily-created map of
1688    // queue -> linked list of updates. After this render pass, we'll restart
1689    // and apply the stashed updates on top of the work-in-progress hook.
1690    didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
1691  } else {
1692    if (
1693      fiber.lanes === NoLanes &&
1694      (alternate === null || alternate.lanes === NoLanes)
1695    ) {
1696      // The queue is currently empty, which means we can eagerly compute the
1697      // next state before entering the render phase. If the new state is the
1698      // same as the current state, we may be able to bail out entirely.
1699      const lastRenderedReducer = queue.lastRenderedReducer;
1700      if (lastRenderedReducer !== null) {
1701        let prevDispatcher;
1702        if (__DEV__) {
1703          prevDispatcher = ReactCurrentDispatcher.current;
1704          ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
1705        }
1706        try {
1707          const currentState    = (queue.lastRenderedState     );
1708          const eagerState = lastRenderedReducer(currentState, action);
1709          // Stash the eagerly computed state, and the reducer used to compute
1710          // it, on the update object. If the reducer hasn't changed by the
1711          // time we enter the render phase, then the eager state can be used
1712          // without calling the reducer again.
1713          update.eagerReducer = lastRenderedReducer;
1714          update.eagerState = eagerState;
1715          if (is(eagerState, currentState)) {
1716            // Fast path. We can bail out without scheduling React to re-render.
1717            // It's still possible that we'll need to rebase this update later,
1718            // if the component re-renders for a different reason and by that
1719            // time the reducer has changed.
1720            return;
1721          }
1722        } catch (error) {
1723          // Suppress the error. It will throw again in the render phase.
1724        } finally {
1725          if (__DEV__) {
1726            ReactCurrentDispatcher.current = prevDispatcher;
1727          }
1728        }
1729      }
1730    }
1731    if (__DEV__) {
1732      // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
1733      if ('undefined' !== typeof jest) {
1734        warnIfNotScopedWithMatchingAct(fiber);
1735        warnIfNotCurrentlyActingUpdatesInDev(fiber);
1736      }
1737    }
1738    scheduleUpdateOnFiber(fiber, lane, eventTime);
1739  }
1740
1741  if (__DEV__) {
1742    if (enableDebugTracing) {
1743      if (fiber.mode & DebugTracingMode) {
1744        const name = getComponentName(fiber.type) || 'Unknown';
1745        logStateUpdateScheduled(name, lane, action);
1746      }
1747    }
1748  }
1749
1750  if (enableSchedulingProfiler) {
1751    markStateUpdateScheduled(fiber, lane);
1752  }
1753}
1754
1755export const ContextOnlyDispatcher             = {
1756  readContext,
1757
1758  useCallback: throwInvalidHookError,
1759  useContext: throwInvalidHookError,
1760  useEffect: throwInvalidHookError,
1761  useImperativeHandle: throwInvalidHookError,
1762  useLayoutEffect: throwInvalidHookError,
1763  useMemo: throwInvalidHookError,
1764  useReducer: throwInvalidHookError,
1765  useRef: throwInvalidHookError,
1766  useState: throwInvalidHookError,
1767  useDebugValue: throwInvalidHookError,
1768  useDeferredValue: throwInvalidHookError,
1769  useTransition: throwInvalidHookError,
1770  useMutableSource: throwInvalidHookError,
1771  useOpaqueIdentifier: throwInvalidHookError,
1772
1773  unstable_isNewReconciler: enableNewReconciler,
1774};
1775
1776const HooksDispatcherOnMount             = {
1777  readContext,
1778
1779  useCallback: mountCallback,
1780  useContext: readContext,
1781  useEffect: mountEffect,
1782  useImperativeHandle: mountImperativeHandle,
1783  useLayoutEffect: mountLayoutEffect,
1784  useMemo: mountMemo,
1785  useReducer: mountReducer,
1786  useRef: mountRef,
1787  useState: mountState,
1788  useDebugValue: mountDebugValue,
1789  useDeferredValue: mountDeferredValue,
1790  useTransition: mountTransition,
1791  useMutableSource: mountMutableSource,
1792  useOpaqueIdentifier: mountOpaqueIdentifier,
1793
1794  unstable_isNewReconciler: enableNewReconciler,
1795};
1796
1797const HooksDispatcherOnUpdate             = {
1798  readContext,
1799
1800  useCallback: updateCallback,
1801  useContext: readContext,
1802  useEffect: updateEffect,
1803  useImperativeHandle: updateImperativeHandle,
1804  useLayoutEffect: updateLayoutEffect,
1805  useMemo: updateMemo,
1806  useReducer: updateReducer,
1807  useRef: updateRef,
1808  useState: updateState,
1809  useDebugValue: updateDebugValue,
1810  useDeferredValue: updateDeferredValue,
1811  useTransition: updateTransition,
1812  useMutableSource: updateMutableSource,
1813  useOpaqueIdentifier: updateOpaqueIdentifier,
1814
1815  unstable_isNewReconciler: enableNewReconciler,
1816};
1817
1818const HooksDispatcherOnRerender             = {
1819  readContext,
1820
1821  useCallback: updateCallback,
1822  useContext: readContext,
1823  useEffect: updateEffect,
1824  useImperativeHandle: updateImperativeHandle,
1825  useLayoutEffect: updateLayoutEffect,
1826  useMemo: updateMemo,
1827  useReducer: rerenderReducer,
1828  useRef: updateRef,
1829  useState: rerenderState,
1830  useDebugValue: updateDebugValue,
1831  useDeferredValue: rerenderDeferredValue,
1832  useTransition: rerenderTransition,
1833  useMutableSource: updateMutableSource,
1834  useOpaqueIdentifier: rerenderOpaqueIdentifier,
1835
1836  unstable_isNewReconciler: enableNewReconciler,
1837};
1838
1839let HooksDispatcherOnMountInDEV                    = null;
1840let HooksDispatcherOnMountWithHookTypesInDEV                    = null;
1841let HooksDispatcherOnUpdateInDEV                    = null;
1842let HooksDispatcherOnRerenderInDEV                    = null;
1843let InvalidNestedHooksDispatcherOnMountInDEV                    = null;
1844let InvalidNestedHooksDispatcherOnUpdateInDEV                    = null;
1845let InvalidNestedHooksDispatcherOnRerenderInDEV                    = null;
1846
1847if (__DEV__) {
1848  const warnInvalidContextAccess = () => {
1849    console.error(
1850      'Context can only be read while React is rendering. ' +
1851        'In classes, you can read it in the render method or getDerivedStateFromProps. ' +
1852        'In function components, you can read it directly in the function body, but not ' +
1853        'inside Hooks like useReducer() or useMemo().',
1854    );
1855  };
1856
1857  const warnInvalidHookAccess = () => {
1858    console.error(
1859      'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +
1860        'You can only call Hooks at the top level of your React function. ' +
1861        'For more information, see ' +
1862        'https://reactjs.org/link/rules-of-hooks',
1863    );
1864  };
1865
1866  HooksDispatcherOnMountInDEV = {
1867    readContext   (
1868      context                 ,
1869      observedBits                         ,
1870    )    {
1871      return readContext(context, observedBits);
1872    },
1873    useCallback   (callback   , deps                            )    {
1874      currentHookNameInDev = 'useCallback';
1875      mountHookTypesDev();
1876      checkDepsAreArrayDev(deps);
1877      return mountCallback(callback, deps);
1878    },
1879    useContext   (
1880      context                 ,
1881      observedBits                         ,
1882    )    {
1883      currentHookNameInDev = 'useContext';
1884      mountHookTypesDev();
1885      return readContext(context, observedBits);
1886    },
1887    useEffect(
1888      create                           ,
1889      deps                            ,
1890    )       {
1891      currentHookNameInDev = 'useEffect';
1892      mountHookTypesDev();
1893      checkDepsAreArrayDev(deps);
1894      return mountEffect(create, deps);
1895    },
1896    useImperativeHandle   (
1897      ref                                                                   ,
1898      create         ,
1899      deps                            ,
1900    )       {
1901      currentHookNameInDev = 'useImperativeHandle';
1902      mountHookTypesDev();
1903      checkDepsAreArrayDev(deps);
1904      return mountImperativeHandle(ref, create, deps);
1905    },
1906    useLayoutEffect(
1907      create                           ,
1908      deps                            ,
1909    )       {
1910      currentHookNameInDev = 'useLayoutEffect';
1911      mountHookTypesDev();
1912      checkDepsAreArrayDev(deps);
1913      return mountLayoutEffect(create, deps);
1914    },
1915    useMemo   (create         , deps                            )    {
1916      currentHookNameInDev = 'useMemo';
1917      mountHookTypesDev();
1918      checkDepsAreArrayDev(deps);
1919      const prevDispatcher = ReactCurrentDispatcher.current;
1920      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
1921      try {
1922        return mountMemo(create, deps);
1923      } finally {
1924        ReactCurrentDispatcher.current = prevDispatcher;
1925      }
1926    },
1927    useReducer         (
1928      reducer             ,
1929      initialArg   ,
1930      init         ,
1931    )                   {
1932      currentHookNameInDev = 'useReducer';
1933      mountHookTypesDev();
1934      const prevDispatcher = ReactCurrentDispatcher.current;
1935      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
1936      try {
1937        return mountReducer(reducer, initialArg, init);
1938      } finally {
1939        ReactCurrentDispatcher.current = prevDispatcher;
1940      }
1941    },
1942    useRef   (initialValue   )                 {
1943      currentHookNameInDev = 'useRef';
1944      mountHookTypesDev();
1945      return mountRef(initialValue);
1946    },
1947    useState   (
1948      initialState               ,
1949    )                                     {
1950      currentHookNameInDev = 'useState';
1951      mountHookTypesDev();
1952      const prevDispatcher = ReactCurrentDispatcher.current;
1953      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
1954      try {
1955        return mountState(initialState);
1956      } finally {
1957        ReactCurrentDispatcher.current = prevDispatcher;
1958      }
1959    },
1960    useDebugValue   (value   , formatterFn                      )       {
1961      currentHookNameInDev = 'useDebugValue';
1962      mountHookTypesDev();
1963      return mountDebugValue(value, formatterFn);
1964    },
1965    useDeferredValue   (value   )    {
1966      currentHookNameInDev = 'useDeferredValue';
1967      mountHookTypesDev();
1968      return mountDeferredValue(value);
1969    },
1970    useTransition()                                  {
1971      currentHookNameInDev = 'useTransition';
1972      mountHookTypesDev();
1973      return mountTransition();
1974    },
1975    useMutableSource                  (
1976      source                       ,
1977      getSnapshot                                              ,
1978      subscribe                                            ,
1979    )           {
1980      currentHookNameInDev = 'useMutableSource';
1981      mountHookTypesDev();
1982      return mountMutableSource(source, getSnapshot, subscribe);
1983    },
1984    useOpaqueIdentifier()                      {
1985      currentHookNameInDev = 'useOpaqueIdentifier';
1986      mountHookTypesDev();
1987      return mountOpaqueIdentifier();
1988    },
1989
1990    unstable_isNewReconciler: enableNewReconciler,
1991  };
1992
1993  HooksDispatcherOnMountWithHookTypesInDEV = {
1994    readContext   (
1995      context                 ,
1996      observedBits                         ,
1997    )    {
1998      return readContext(context, observedBits);
1999    },
2000    useCallback   (callback   , deps                            )    {
2001      currentHookNameInDev = 'useCallback';
2002      updateHookTypesDev();
2003      return mountCallback(callback, deps);
2004    },
2005    useContext   (
2006      context                 ,
2007      observedBits                         ,
2008    )    {
2009      currentHookNameInDev = 'useContext';
2010      updateHookTypesDev();
2011      return readContext(context, observedBits);
2012    },
2013    useEffect(
2014      create                           ,
2015      deps                            ,
2016    )       {
2017      currentHookNameInDev = 'useEffect';
2018      updateHookTypesDev();
2019      return mountEffect(create, deps);
2020    },
2021    useImperativeHandle   (
2022      ref                                                                   ,
2023      create         ,
2024      deps                            ,
2025    )       {
2026      currentHookNameInDev = 'useImperativeHandle';
2027      updateHookTypesDev();
2028      return mountImperativeHandle(ref, create, deps);
2029    },
2030    useLayoutEffect(
2031      create                           ,
2032      deps                            ,
2033    )       {
2034      currentHookNameInDev = 'useLayoutEffect';
2035      updateHookTypesDev();
2036      return mountLayoutEffect(create, deps);
2037    },
2038    useMemo   (create         , deps                            )    {
2039      currentHookNameInDev = 'useMemo';
2040      updateHookTypesDev();
2041      const prevDispatcher = ReactCurrentDispatcher.current;
2042      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
2043      try {
2044        return mountMemo(create, deps);
2045      } finally {
2046        ReactCurrentDispatcher.current = prevDispatcher;
2047      }
2048    },
2049    useReducer         (
2050      reducer             ,
2051      initialArg   ,
2052      init         ,
2053    )                   {
2054      currentHookNameInDev = 'useReducer';
2055      updateHookTypesDev();
2056      const prevDispatcher = ReactCurrentDispatcher.current;
2057      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
2058      try {
2059        return mountReducer(reducer, initialArg, init);
2060      } finally {
2061        ReactCurrentDispatcher.current = prevDispatcher;
2062      }
2063    },
2064    useRef   (initialValue   )                 {
2065      currentHookNameInDev = 'useRef';
2066      updateHookTypesDev();
2067      return mountRef(initialValue);
2068    },
2069    useState   (
2070      initialState               ,
2071    )                                     {
2072      currentHookNameInDev = 'useState';
2073      updateHookTypesDev();
2074      const prevDispatcher = ReactCurrentDispatcher.current;
2075      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
2076      try {
2077        return mountState(initialState);
2078      } finally {
2079        ReactCurrentDispatcher.current = prevDispatcher;
2080      }
2081    },
2082    useDebugValue   (value   , formatterFn                      )       {
2083      currentHookNameInDev = 'useDebugValue';
2084      updateHookTypesDev();
2085      return mountDebugValue(value, formatterFn);
2086    },
2087    useDeferredValue   (value   )    {
2088      currentHookNameInDev = 'useDeferredValue';
2089      updateHookTypesDev();
2090      return mountDeferredValue(value);
2091    },
2092    useTransition()                                  {
2093      currentHookNameInDev = 'useTransition';
2094      updateHookTypesDev();
2095      return mountTransition();
2096    },
2097    useMutableSource                  (
2098      source                       ,
2099      getSnapshot                                              ,
2100      subscribe                                            ,
2101    )           {
2102      currentHookNameInDev = 'useMutableSource';
2103      updateHookTypesDev();
2104      return mountMutableSource(source, getSnapshot, subscribe);
2105    },
2106    useOpaqueIdentifier()                      {
2107      currentHookNameInDev = 'useOpaqueIdentifier';
2108      updateHookTypesDev();
2109      return mountOpaqueIdentifier();
2110    },
2111
2112    unstable_isNewReconciler: enableNewReconciler,
2113  };
2114
2115  HooksDispatcherOnUpdateInDEV = {
2116    readContext   (
2117      context                 ,
2118      observedBits                         ,
2119    )    {
2120      return readContext(context, observedBits);
2121    },
2122    useCallback   (callback   , deps                            )    {
2123      currentHookNameInDev = 'useCallback';
2124      updateHookTypesDev();
2125      return updateCallback(callback, deps);
2126    },
2127    useContext   (
2128      context                 ,
2129      observedBits                         ,
2130    )    {
2131      currentHookNameInDev = 'useContext';
2132      updateHookTypesDev();
2133      return readContext(context, observedBits);
2134    },
2135    useEffect(
2136      create                           ,
2137      deps                            ,
2138    )       {
2139      currentHookNameInDev = 'useEffect';
2140      updateHookTypesDev();
2141      return updateEffect(create, deps);
2142    },
2143    useImperativeHandle   (
2144      ref                                                                   ,
2145      create         ,
2146      deps                            ,
2147    )       {
2148      currentHookNameInDev = 'useImperativeHandle';
2149      updateHookTypesDev();
2150      return updateImperativeHandle(ref, create, deps);
2151    },
2152    useLayoutEffect(
2153      create                           ,
2154      deps                            ,
2155    )       {
2156      currentHookNameInDev = 'useLayoutEffect';
2157      updateHookTypesDev();
2158      return updateLayoutEffect(create, deps);
2159    },
2160    useMemo   (create         , deps                            )    {
2161      currentHookNameInDev = 'useMemo';
2162      updateHookTypesDev();
2163      const prevDispatcher = ReactCurrentDispatcher.current;
2164      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2165      try {
2166        return updateMemo(create, deps);
2167      } finally {
2168        ReactCurrentDispatcher.current = prevDispatcher;
2169      }
2170    },
2171    useReducer         (
2172      reducer             ,
2173      initialArg   ,
2174      init         ,
2175    )                   {
2176      currentHookNameInDev = 'useReducer';
2177      updateHookTypesDev();
2178      const prevDispatcher = ReactCurrentDispatcher.current;
2179      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2180      try {
2181        return updateReducer(reducer, initialArg, init);
2182      } finally {
2183        ReactCurrentDispatcher.current = prevDispatcher;
2184      }
2185    },
2186    useRef   (initialValue   )                 {
2187      currentHookNameInDev = 'useRef';
2188      updateHookTypesDev();
2189      return updateRef(initialValue);
2190    },
2191    useState   (
2192      initialState               ,
2193    )                                     {
2194      currentHookNameInDev = 'useState';
2195      updateHookTypesDev();
2196      const prevDispatcher = ReactCurrentDispatcher.current;
2197      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2198      try {
2199        return updateState(initialState);
2200      } finally {
2201        ReactCurrentDispatcher.current = prevDispatcher;
2202      }
2203    },
2204    useDebugValue   (value   , formatterFn                      )       {
2205      currentHookNameInDev = 'useDebugValue';
2206      updateHookTypesDev();
2207      return updateDebugValue(value, formatterFn);
2208    },
2209    useDeferredValue   (value   )    {
2210      currentHookNameInDev = 'useDeferredValue';
2211      updateHookTypesDev();
2212      return updateDeferredValue(value);
2213    },
2214    useTransition()                                  {
2215      currentHookNameInDev = 'useTransition';
2216      updateHookTypesDev();
2217      return updateTransition();
2218    },
2219    useMutableSource                  (
2220      source                       ,
2221      getSnapshot                                              ,
2222      subscribe                                            ,
2223    )           {
2224      currentHookNameInDev = 'useMutableSource';
2225      updateHookTypesDev();
2226      return updateMutableSource(source, getSnapshot, subscribe);
2227    },
2228    useOpaqueIdentifier()                      {
2229      currentHookNameInDev = 'useOpaqueIdentifier';
2230      updateHookTypesDev();
2231      return updateOpaqueIdentifier();
2232    },
2233
2234    unstable_isNewReconciler: enableNewReconciler,
2235  };
2236
2237  HooksDispatcherOnRerenderInDEV = {
2238    readContext   (
2239      context                 ,
2240      observedBits                         ,
2241    )    {
2242      return readContext(context, observedBits);
2243    },
2244
2245    useCallback   (callback   , deps                            )    {
2246      currentHookNameInDev = 'useCallback';
2247      updateHookTypesDev();
2248      return updateCallback(callback, deps);
2249    },
2250    useContext   (
2251      context                 ,
2252      observedBits                         ,
2253    )    {
2254      currentHookNameInDev = 'useContext';
2255      updateHookTypesDev();
2256      return readContext(context, observedBits);
2257    },
2258    useEffect(
2259      create                           ,
2260      deps                            ,
2261    )       {
2262      currentHookNameInDev = 'useEffect';
2263      updateHookTypesDev();
2264      return updateEffect(create, deps);
2265    },
2266    useImperativeHandle   (
2267      ref                                                                   ,
2268      create         ,
2269      deps                            ,
2270    )       {
2271      currentHookNameInDev = 'useImperativeHandle';
2272      updateHookTypesDev();
2273      return updateImperativeHandle(ref, create, deps);
2274    },
2275    useLayoutEffect(
2276      create                           ,
2277      deps                            ,
2278    )       {
2279      currentHookNameInDev = 'useLayoutEffect';
2280      updateHookTypesDev();
2281      return updateLayoutEffect(create, deps);
2282    },
2283    useMemo   (create         , deps                            )    {
2284      currentHookNameInDev = 'useMemo';
2285      updateHookTypesDev();
2286      const prevDispatcher = ReactCurrentDispatcher.current;
2287      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
2288      try {
2289        return updateMemo(create, deps);
2290      } finally {
2291        ReactCurrentDispatcher.current = prevDispatcher;
2292      }
2293    },
2294    useReducer         (
2295      reducer             ,
2296      initialArg   ,
2297      init         ,
2298    )                   {
2299      currentHookNameInDev = 'useReducer';
2300      updateHookTypesDev();
2301      const prevDispatcher = ReactCurrentDispatcher.current;
2302      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
2303      try {
2304        return rerenderReducer(reducer, initialArg, init);
2305      } finally {
2306        ReactCurrentDispatcher.current = prevDispatcher;
2307      }
2308    },
2309    useRef   (initialValue   )                 {
2310      currentHookNameInDev = 'useRef';
2311      updateHookTypesDev();
2312      return updateRef(initialValue);
2313    },
2314    useState   (
2315      initialState               ,
2316    )                                     {
2317      currentHookNameInDev = 'useState';
2318      updateHookTypesDev();
2319      const prevDispatcher = ReactCurrentDispatcher.current;
2320      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
2321      try {
2322        return rerenderState(initialState);
2323      } finally {
2324        ReactCurrentDispatcher.current = prevDispatcher;
2325      }
2326    },
2327    useDebugValue   (value   , formatterFn                      )       {
2328      currentHookNameInDev = 'useDebugValue';
2329      updateHookTypesDev();
2330      return updateDebugValue(value, formatterFn);
2331    },
2332    useDeferredValue   (value   )    {
2333      currentHookNameInDev = 'useDeferredValue';
2334      updateHookTypesDev();
2335      return rerenderDeferredValue(value);
2336    },
2337    useTransition()                                  {
2338      currentHookNameInDev = 'useTransition';
2339      updateHookTypesDev();
2340      return rerenderTransition();
2341    },
2342    useMutableSource                  (
2343      source                       ,
2344      getSnapshot                                              ,
2345      subscribe                                            ,
2346    )           {
2347      currentHookNameInDev = 'useMutableSource';
2348      updateHookTypesDev();
2349      return updateMutableSource(source, getSnapshot, subscribe);
2350    },
2351    useOpaqueIdentifier()                      {
2352      currentHookNameInDev = 'useOpaqueIdentifier';
2353      updateHookTypesDev();
2354      return rerenderOpaqueIdentifier();
2355    },
2356
2357    unstable_isNewReconciler: enableNewReconciler,
2358  };
2359
2360  InvalidNestedHooksDispatcherOnMountInDEV = {
2361    readContext   (
2362      context                 ,
2363      observedBits                         ,
2364    )    {
2365      warnInvalidContextAccess();
2366      return readContext(context, observedBits);
2367    },
2368    useCallback   (callback   , deps                            )    {
2369      currentHookNameInDev = 'useCallback';
2370      warnInvalidHookAccess();
2371      mountHookTypesDev();
2372      return mountCallback(callback, deps);
2373    },
2374    useContext   (
2375      context                 ,
2376      observedBits                         ,
2377    )    {
2378      currentHookNameInDev = 'useContext';
2379      warnInvalidHookAccess();
2380      mountHookTypesDev();
2381      return readContext(context, observedBits);
2382    },
2383    useEffect(
2384      create                           ,
2385      deps                            ,
2386    )       {
2387      currentHookNameInDev = 'useEffect';
2388      warnInvalidHookAccess();
2389      mountHookTypesDev();
2390      return mountEffect(create, deps);
2391    },
2392    useImperativeHandle   (
2393      ref                                                                   ,
2394      create         ,
2395      deps                            ,
2396    )       {
2397      currentHookNameInDev = 'useImperativeHandle';
2398      warnInvalidHookAccess();
2399      mountHookTypesDev();
2400      return mountImperativeHandle(ref, create, deps);
2401    },
2402    useLayoutEffect(
2403      create                           ,
2404      deps                            ,
2405    )       {
2406      currentHookNameInDev = 'useLayoutEffect';
2407      warnInvalidHookAccess();
2408      mountHookTypesDev();
2409      return mountLayoutEffect(create, deps);
2410    },
2411    useMemo   (create         , deps                            )    {
2412      currentHookNameInDev = 'useMemo';
2413      warnInvalidHookAccess();
2414      mountHookTypesDev();
2415      const prevDispatcher = ReactCurrentDispatcher.current;
2416      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
2417      try {
2418        return mountMemo(create, deps);
2419      } finally {
2420        ReactCurrentDispatcher.current = prevDispatcher;
2421      }
2422    },
2423    useReducer         (
2424      reducer             ,
2425      initialArg   ,
2426      init         ,
2427    )                   {
2428      currentHookNameInDev = 'useReducer';
2429      warnInvalidHookAccess();
2430      mountHookTypesDev();
2431      const prevDispatcher = ReactCurrentDispatcher.current;
2432      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
2433      try {
2434        return mountReducer(reducer, initialArg, init);
2435      } finally {
2436        ReactCurrentDispatcher.current = prevDispatcher;
2437      }
2438    },
2439    useRef   (initialValue   )                 {
2440      currentHookNameInDev = 'useRef';
2441      warnInvalidHookAccess();
2442      mountHookTypesDev();
2443      return mountRef(initialValue);
2444    },
2445    useState   (
2446      initialState               ,
2447    )                                     {
2448      currentHookNameInDev = 'useState';
2449      warnInvalidHookAccess();
2450      mountHookTypesDev();
2451      const prevDispatcher = ReactCurrentDispatcher.current;
2452      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
2453      try {
2454        return mountState(initialState);
2455      } finally {
2456        ReactCurrentDispatcher.current = prevDispatcher;
2457      }
2458    },
2459    useDebugValue   (value   , formatterFn                      )       {
2460      currentHookNameInDev = 'useDebugValue';
2461      warnInvalidHookAccess();
2462      mountHookTypesDev();
2463      return mountDebugValue(value, formatterFn);
2464    },
2465    useDeferredValue   (value   )    {
2466      currentHookNameInDev = 'useDeferredValue';
2467      warnInvalidHookAccess();
2468      mountHookTypesDev();
2469      return mountDeferredValue(value);
2470    },
2471    useTransition()                                  {
2472      currentHookNameInDev = 'useTransition';
2473      warnInvalidHookAccess();
2474      mountHookTypesDev();
2475      return mountTransition();
2476    },
2477    useMutableSource                  (
2478      source                       ,
2479      getSnapshot                                              ,
2480      subscribe                                            ,
2481    )           {
2482      currentHookNameInDev = 'useMutableSource';
2483      warnInvalidHookAccess();
2484      mountHookTypesDev();
2485      return mountMutableSource(source, getSnapshot, subscribe);
2486    },
2487    useOpaqueIdentifier()                      {
2488      currentHookNameInDev = 'useOpaqueIdentifier';
2489      warnInvalidHookAccess();
2490      mountHookTypesDev();
2491      return mountOpaqueIdentifier();
2492    },
2493
2494    unstable_isNewReconciler: enableNewReconciler,
2495  };
2496
2497  InvalidNestedHooksDispatcherOnUpdateInDEV = {
2498    readContext   (
2499      context                 ,
2500      observedBits                         ,
2501    )    {
2502      warnInvalidContextAccess();
2503      return readContext(context, observedBits);
2504    },
2505    useCallback   (callback   , deps                            )    {
2506      currentHookNameInDev = 'useCallback';
2507      warnInvalidHookAccess();
2508      updateHookTypesDev();
2509      return updateCallback(callback, deps);
2510    },
2511    useContext   (
2512      context                 ,
2513      observedBits                         ,
2514    )    {
2515      currentHookNameInDev = 'useContext';
2516      warnInvalidHookAccess();
2517      updateHookTypesDev();
2518      return readContext(context, observedBits);
2519    },
2520    useEffect(
2521      create                           ,
2522      deps                            ,
2523    )       {
2524      currentHookNameInDev = 'useEffect';
2525      warnInvalidHookAccess();
2526      updateHookTypesDev();
2527      return updateEffect(create, deps);
2528    },
2529    useImperativeHandle   (
2530      ref                                                                   ,
2531      create         ,
2532      deps                            ,
2533    )       {
2534      currentHookNameInDev = 'useImperativeHandle';
2535      warnInvalidHookAccess();
2536      updateHookTypesDev();
2537      return updateImperativeHandle(ref, create, deps);
2538    },
2539    useLayoutEffect(
2540      create                           ,
2541      deps                            ,
2542    )       {
2543      currentHookNameInDev = 'useLayoutEffect';
2544      warnInvalidHookAccess();
2545      updateHookTypesDev();
2546      return updateLayoutEffect(create, deps);
2547    },
2548    useMemo   (create         , deps                            )    {
2549      currentHookNameInDev = 'useMemo';
2550      warnInvalidHookAccess();
2551      updateHookTypesDev();
2552      const prevDispatcher = ReactCurrentDispatcher.current;
2553      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2554      try {
2555        return updateMemo(create, deps);
2556      } finally {
2557        ReactCurrentDispatcher.current = prevDispatcher;
2558      }
2559    },
2560    useReducer         (
2561      reducer             ,
2562      initialArg   ,
2563      init         ,
2564    )                   {
2565      currentHookNameInDev = 'useReducer';
2566      warnInvalidHookAccess();
2567      updateHookTypesDev();
2568      const prevDispatcher = ReactCurrentDispatcher.current;
2569      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2570      try {
2571        return updateReducer(reducer, initialArg, init);
2572      } finally {
2573        ReactCurrentDispatcher.current = prevDispatcher;
2574      }
2575    },
2576    useRef   (initialValue   )                 {
2577      currentHookNameInDev = 'useRef';
2578      warnInvalidHookAccess();
2579      updateHookTypesDev();
2580      return updateRef(initialValue);
2581    },
2582    useState   (
2583      initialState               ,
2584    )                                     {
2585      currentHookNameInDev = 'useState';
2586      warnInvalidHookAccess();
2587      updateHookTypesDev();
2588      const prevDispatcher = ReactCurrentDispatcher.current;
2589      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2590      try {
2591        return updateState(initialState);
2592      } finally {
2593        ReactCurrentDispatcher.current = prevDispatcher;
2594      }
2595    },
2596    useDebugValue   (value   , formatterFn                      )       {
2597      currentHookNameInDev = 'useDebugValue';
2598      warnInvalidHookAccess();
2599      updateHookTypesDev();
2600      return updateDebugValue(value, formatterFn);
2601    },
2602    useDeferredValue   (value   )    {
2603      currentHookNameInDev = 'useDeferredValue';
2604      warnInvalidHookAccess();
2605      updateHookTypesDev();
2606      return updateDeferredValue(value);
2607    },
2608    useTransition()                                  {
2609      currentHookNameInDev = 'useTransition';
2610      warnInvalidHookAccess();
2611      updateHookTypesDev();
2612      return updateTransition();
2613    },
2614    useMutableSource                  (
2615      source                       ,
2616      getSnapshot                                              ,
2617      subscribe                                            ,
2618    )           {
2619      currentHookNameInDev = 'useMutableSource';
2620      warnInvalidHookAccess();
2621      updateHookTypesDev();
2622      return updateMutableSource(source, getSnapshot, subscribe);
2623    },
2624    useOpaqueIdentifier()                      {
2625      currentHookNameInDev = 'useOpaqueIdentifier';
2626      warnInvalidHookAccess();
2627      updateHookTypesDev();
2628      return updateOpaqueIdentifier();
2629    },
2630
2631    unstable_isNewReconciler: enableNewReconciler,
2632  };
2633
2634  InvalidNestedHooksDispatcherOnRerenderInDEV = {
2635    readContext   (
2636      context                 ,
2637      observedBits                         ,
2638    )    {
2639      warnInvalidContextAccess();
2640      return readContext(context, observedBits);
2641    },
2642
2643    useCallback   (callback   , deps                            )    {
2644      currentHookNameInDev = 'useCallback';
2645      warnInvalidHookAccess();
2646      updateHookTypesDev();
2647      return updateCallback(callback, deps);
2648    },
2649    useContext   (
2650      context                 ,
2651      observedBits                         ,
2652    )    {
2653      currentHookNameInDev = 'useContext';
2654      warnInvalidHookAccess();
2655      updateHookTypesDev();
2656      return readContext(context, observedBits);
2657    },
2658    useEffect(
2659      create                           ,
2660      deps                            ,
2661    )       {
2662      currentHookNameInDev = 'useEffect';
2663      warnInvalidHookAccess();
2664      updateHookTypesDev();
2665      return updateEffect(create, deps);
2666    },
2667    useImperativeHandle   (
2668      ref                                                                   ,
2669      create         ,
2670      deps                            ,
2671    )       {
2672      currentHookNameInDev = 'useImperativeHandle';
2673      warnInvalidHookAccess();
2674      updateHookTypesDev();
2675      return updateImperativeHandle(ref, create, deps);
2676    },
2677    useLayoutEffect(
2678      create                           ,
2679      deps                            ,
2680    )       {
2681      currentHookNameInDev = 'useLayoutEffect';
2682      warnInvalidHookAccess();
2683      updateHookTypesDev();
2684      return updateLayoutEffect(create, deps);
2685    },
2686    useMemo   (create         , deps                            )    {
2687      currentHookNameInDev = 'useMemo';
2688      warnInvalidHookAccess();
2689      updateHookTypesDev();
2690      const prevDispatcher = ReactCurrentDispatcher.current;
2691      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2692      try {
2693        return updateMemo(create, deps);
2694      } finally {
2695        ReactCurrentDispatcher.current = prevDispatcher;
2696      }
2697    },
2698    useReducer         (
2699      reducer             ,
2700      initialArg   ,
2701      init         ,
2702    )                   {
2703      currentHookNameInDev = 'useReducer';
2704      warnInvalidHookAccess();
2705      updateHookTypesDev();
2706      const prevDispatcher = ReactCurrentDispatcher.current;
2707      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2708      try {
2709        return rerenderReducer(reducer, initialArg, init);
2710      } finally {
2711        ReactCurrentDispatcher.current = prevDispatcher;
2712      }
2713    },
2714    useRef   (initialValue   )                 {
2715      currentHookNameInDev = 'useRef';
2716      warnInvalidHookAccess();
2717      updateHookTypesDev();
2718      return updateRef(initialValue);
2719    },
2720    useState   (
2721      initialState               ,
2722    )                                     {
2723      currentHookNameInDev = 'useState';
2724      warnInvalidHookAccess();
2725      updateHookTypesDev();
2726      const prevDispatcher = ReactCurrentDispatcher.current;
2727      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
2728      try {
2729        return rerenderState(initialState);
2730      } finally {
2731        ReactCurrentDispatcher.current = prevDispatcher;
2732      }
2733    },
2734    useDebugValue   (value   , formatterFn                      )       {
2735      currentHookNameInDev = 'useDebugValue';
2736      warnInvalidHookAccess();
2737      updateHookTypesDev();
2738      return updateDebugValue(value, formatterFn);
2739    },
2740    useDeferredValue   (value   )    {
2741      currentHookNameInDev = 'useDeferredValue';
2742      warnInvalidHookAccess();
2743      updateHookTypesDev();
2744      return rerenderDeferredValue(value);
2745    },
2746    useTransition()                                  {
2747      currentHookNameInDev = 'useTransition';
2748      warnInvalidHookAccess();
2749      updateHookTypesDev();
2750      return rerenderTransition();
2751    },
2752    useMutableSource                  (
2753      source                       ,
2754      getSnapshot                                              ,
2755      subscribe                                            ,
2756    )           {
2757      currentHookNameInDev = 'useMutableSource';
2758      warnInvalidHookAccess();
2759      updateHookTypesDev();
2760      return updateMutableSource(source, getSnapshot, subscribe);
2761    },
2762    useOpaqueIdentifier()                      {
2763      currentHookNameInDev = 'useOpaqueIdentifier';
2764      warnInvalidHookAccess();
2765      updateHookTypesDev();
2766      return rerenderOpaqueIdentifier();
2767    },
2768
2769    unstable_isNewReconciler: enableNewReconciler,
2770  };
2771}
2772
Full Screen

ReactFiberHooks.new.js

Source: ReactFiberHooks.new.js Github

copy
1/**
2 * Copyright (c) Facebook, Inc. and its 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 *      
8 */
9
10             
11                
12                             
13                           
14               
15                           
16                                                            
17                                                  
18                                                     
19                                                             
20                                                    
21                                                         
22
23import ReactSharedInternals from 'shared/ReactSharedInternals';
24import {
25  enableDebugTracing,
26  enableSchedulingProfiler,
27  enableNewReconciler,
28  decoupleUpdatePriorityFromScheduler,
29  enableDoubleInvokingEffects,
30} from 'shared/ReactFeatureFlags';
31
32import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
33import {
34  NoLane,
35  NoLanes,
36  InputContinuousLanePriority,
37  isSubsetOfLanes,
38  mergeLanes,
39  removeLanes,
40  markRootEntangled,
41  markRootMutableRead,
42  getCurrentUpdateLanePriority,
43  setCurrentUpdateLanePriority,
44  higherLanePriority,
45  DefaultLanePriority,
46} from './ReactFiberLane';
47import {readContext} from './ReactFiberNewContext.new';
48import {
49  Update as UpdateEffect,
50  Passive as PassiveEffect,
51  PassiveStatic as PassiveStaticEffect,
52  MountLayoutDev as MountLayoutDevEffect,
53  MountPassiveDev as MountPassiveDevEffect,
54} from './ReactFiberFlags';
55import {
56  HasEffect as HookHasEffect,
57  Layout as HookLayout,
58  Passive as HookPassive,
59} from './ReactHookEffectTags';
60import {
61  getWorkInProgressRoot,
62  scheduleUpdateOnFiber,
63  requestUpdateLane,
64  requestEventTime,
65  warnIfNotCurrentlyActingEffectsInDEV,
66  warnIfNotCurrentlyActingUpdatesInDev,
67  warnIfNotScopedWithMatchingAct,
68  markSkippedUpdateLanes,
69} from './ReactFiberWorkLoop.new';
70
71import invariant from 'shared/invariant';
72import getComponentName from 'shared/getComponentName';
73import is from 'shared/objectIs';
74import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork.new';
75import {
76  UserBlockingPriority,
77  NormalPriority,
78  runWithPriority,
79  getCurrentPriorityLevel,
80} from './SchedulerWithReactIntegration.new';
81import {getIsHydrating} from './ReactFiberHydrationContext.new';
82import {
83  makeClientId,
84  makeClientIdInDEV,
85  makeOpaqueHydratingObject,
86} from './ReactFiberHostConfig';
87import {
88  getWorkInProgressVersion,
89  markSourceAsDirty,
90  setWorkInProgressVersion,
91  warnAboutMultipleRenderersDEV,
92} from './ReactMutableSource.new';
93import {getIsRendering} from './ReactCurrentFiber';
94import {logStateUpdateScheduled} from './DebugTracing';
95import {markStateUpdateScheduled} from './SchedulingProfiler';
96
97const {ReactCurrentDispatcher, ReactCurrentBatchConfig} = ReactSharedInternals;
98
99                      
100             
101            
102                                     
103                       
104                     
105                                
106   
107
108                           
109                               
110                                
111                                            
112                              
113   
114
115                      
116              
117                
118                
119            
120               
121                     
122                 
123             
124                         
125                   
126                      
127                   
128                      
129                          
130
131let didWarnAboutMismatchedHooksForComponent;
132let didWarnAboutUseOpaqueIdentifier;
133if (__DEV__) {
134  didWarnAboutUseOpaqueIdentifier = {};
135  didWarnAboutMismatchedHooksForComponent = new Set();
136}
137
138                     
139                     
140                 
141                                     
142                                      
143                    
144   
145
146                       
147                 
148                                    
149                               
150                            
151               
152   
153
154                                                                         
155
156                                        
157
158                             
159
160// These are set right before calling the component.
161let renderLanes        = NoLanes;
162// The work-in-progress fiber. I've named it differently to distinguish it from
163