| 3753 | } |
| 3754 | |
| 3755 | function remountFiber( |
| 3756 | current: Fiber, |
| 3757 | oldWorkInProgress: Fiber, |
| 3758 | newWorkInProgress: Fiber, |
| 3759 | ): Fiber | null { |
| 3760 | if (__DEV__) { |
| 3761 | const returnFiber = oldWorkInProgress.return; |
| 3762 | if (returnFiber === null) { |
| 3763 | // eslint-disable-next-line react-internal/prod-error-codes |
| 3764 | throw new Error('Cannot swap the root fiber.'); |
| 3765 | } |
| 3766 | |
| 3767 | // Disconnect from the old current. |
| 3768 | // It will get deleted. |
| 3769 | current.alternate = null; |
| 3770 | oldWorkInProgress.alternate = null; |
| 3771 | |
| 3772 | // Connect to the new tree. |
| 3773 | newWorkInProgress.index = oldWorkInProgress.index; |
| 3774 | newWorkInProgress.sibling = oldWorkInProgress.sibling; |
| 3775 | newWorkInProgress.return = oldWorkInProgress.return; |
| 3776 | newWorkInProgress.ref = oldWorkInProgress.ref; |
| 3777 | |
| 3778 | if (__DEV__) { |
| 3779 | newWorkInProgress._debugInfo = oldWorkInProgress._debugInfo; |
| 3780 | } |
| 3781 | |
| 3782 | // Replace the child/sibling pointers above it. |
| 3783 | if (oldWorkInProgress === returnFiber.child) { |
| 3784 | returnFiber.child = newWorkInProgress; |
| 3785 | } else { |
| 3786 | let prevSibling = returnFiber.child; |
| 3787 | if (prevSibling === null) { |
| 3788 | // eslint-disable-next-line react-internal/prod-error-codes |
| 3789 | throw new Error('Expected parent to have a child.'); |
| 3790 | } |
| 3791 | // $FlowFixMe[incompatible-use] found when upgrading Flow |
| 3792 | while (prevSibling.sibling !== oldWorkInProgress) { |
| 3793 | // $FlowFixMe[incompatible-use] found when upgrading Flow |
| 3794 | prevSibling = prevSibling.sibling; |
| 3795 | if (prevSibling === null) { |
| 3796 | // eslint-disable-next-line react-internal/prod-error-codes |
| 3797 | throw new Error('Expected to find the previous sibling.'); |
| 3798 | } |
| 3799 | } |
| 3800 | // $FlowFixMe[incompatible-use] found when upgrading Flow |
| 3801 | prevSibling.sibling = newWorkInProgress; |
| 3802 | } |
| 3803 | |
| 3804 | // Delete the old fiber and place the new one. |
| 3805 | // Since the old fiber is disconnected, we have to schedule it manually. |
| 3806 | const deletions = returnFiber.deletions; |
| 3807 | if (deletions === null) { |
| 3808 | returnFiber.deletions = [current]; |
| 3809 | returnFiber.flags |= ChildDeletion; |
| 3810 | } else { |
| 3811 | deletions.push(current); |
| 3812 | } |