@@ -181,9 +181,7 @@ let currentlyRenderingFiber: Fiber | null = null;
181
181
// work-in-progress hook list is a new list that will be added to the
182
182
// work-in-progress fiber.
183
183
let currentHook : Hook | null = null ;
184
- let nextCurrentHook : Hook | null = null ;
185
184
let workInProgressHook : Hook | null = null ;
186
- let nextWorkInProgressHook : Hook | null = null ;
187
185
188
186
// Updates scheduled during render will trigger an immediate re-render at the
189
187
// end of the current pass. We can't store these updates on the normal queue,
@@ -379,7 +377,6 @@ export function renderWithHooks(
379
377
): any {
380
378
renderExpirationTime = nextRenderExpirationTime;
381
379
currentlyRenderingFiber = workInProgress;
382
- nextCurrentHook = current !== null ? current.memoizedState : null;
383
380
384
381
if (__DEV__) {
385
382
hookTypesDev =
@@ -404,14 +401,14 @@ export function renderWithHooks(
404
401
// renderPhaseUpdates = null;
405
402
406
403
// TODO Warn if no hooks are used at all during mount, then some are used during update.
407
- // Currently we will identify the update render as a mount because nextCurrentHook === null.
404
+ // Currently we will identify the update render as a mount because memoizedState === null.
408
405
// This is tricky because it's valid for certain types of components (e.g. React.lazy)
409
406
410
- // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
407
+ // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
411
408
// Non-stateful hooks (e.g. context) don't get added to memoizedState,
412
- // so nextCurrentHook would be null during updates and mounts.
409
+ // so memoizedState would be null during updates and mounts.
413
410
if (__DEV__) {
414
- if (nextCurrentHook !== null) {
411
+ if (current !== null && current.memoizedState !== null) {
415
412
ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
416
413
} else if (hookTypesDev !== null) {
417
414
// This dispatcher handles an edge case where a component is updating,
@@ -425,7 +422,7 @@ export function renderWithHooks(
425
422
}
426
423
} else {
427
424
ReactCurrentDispatcher.current =
428
- nextCurrentHook === null
425
+ current === null || current.memoizedState === null
429
426
? HooksDispatcherOnMount
430
427
: HooksDispatcherOnUpdate;
431
428
}
@@ -452,9 +449,6 @@ export function renderWithHooks(
452
449
}
453
450
454
451
// Start over from the beginning of the list
455
- nextCurrentHook = current !== null ? current.memoizedState : null;
456
- nextWorkInProgressHook = workInProgress.memoizedState;
457
-
458
452
currentHook = null;
459
453
workInProgressHook = null;
460
454
@@ -492,9 +486,7 @@ export function renderWithHooks(
492
486
currentlyRenderingFiber = null;
493
487
494
488
currentHook = null;
495
- nextCurrentHook = null;
496
489
workInProgressHook = null;
497
- nextWorkInProgressHook = null;
498
490
499
491
if (__DEV__) {
500
492
currentHookNameInDev = null;
@@ -540,9 +532,7 @@ export function resetHooks(): void {
540
532
currentlyRenderingFiber = null;
541
533
542
534
currentHook = null;
543
- nextCurrentHook = null;
544
535
workInProgressHook = null;
545
- nextWorkInProgressHook = null;
546
536
547
537
if (__DEV__) {
548
538
hookTypesDev = null;
@@ -583,15 +573,36 @@ function updateWorkInProgressHook(): Hook {
583
573
// clone, or a work-in-progress hook from a previous render pass that we can
584
574
// use as a base. When we reach the end of the base list, we must switch to
585
575
// the dispatcher used for mounts.
576
+ let nextCurrentHook: null | Hook;
577
+ if (currentHook === null) {
578
+ let fiber = ((currentlyRenderingFiber: any): Fiber);
579
+ let current = fiber.alternate;
580
+ if (current !== null) {
581
+ nextCurrentHook = current.memoizedState;
582
+ } else {
583
+ nextCurrentHook = null;
584
+ }
585
+ } else {
586
+ nextCurrentHook = currentHook.next;
587
+ }
588
+
589
+ let nextWorkInProgressHook: null | Hook;
590
+ if (workInProgressHook === null) {
591
+ let fiber = ((currentlyRenderingFiber: any): Fiber);
592
+ nextWorkInProgressHook = fiber.memoizedState;
593
+ } else {
594
+ nextWorkInProgressHook = workInProgressHook.next;
595
+ }
596
+
586
597
if (nextWorkInProgressHook !== null) {
587
598
// There's already a work-in-progress. Reuse it.
588
599
workInProgressHook = nextWorkInProgressHook;
589
600
nextWorkInProgressHook = workInProgressHook.next;
590
601
591
602
currentHook = nextCurrentHook;
592
- nextCurrentHook = currentHook !== null ? currentHook.next : null;
593
603
} else {
594
604
// Clone from the current hook.
605
+
595
606
invariant(
596
607
nextCurrentHook !== null,
597
608
'Rendered more hooks than during the previous render.',
@@ -616,7 +627,6 @@ function updateWorkInProgressHook(): Hook {
616
627
// Append to the end of the list.
617
628
workInProgressHook = workInProgressHook.next = newHook;
618
629
}
619
- nextCurrentHook = currentHook.next;
620
630
}
621
631
return workInProgressHook;
622
632
}
0 commit comments