(queue, update)
| 3644 | |
| 3645 | if (isRenderPhaseUpdate(fiber)) { |
| 3646 | enqueueRenderPhaseUpdate(queue, update); |
| 3647 | } else { |
| 3648 | const alternate = fiber.alternate; |
| 3649 | if ( |
| 3650 | fiber.lanes === NoLanes && |
| 3651 | (alternate === null || alternate.lanes === NoLanes) |
| 3652 | ) { |
| 3653 | // The queue is currently empty, which means we can eagerly compute the |
| 3654 | // next state before entering the render phase. If the new state is the |
| 3655 | // same as the current state, we may be able to bail out entirely. |
| 3656 | const lastRenderedReducer = queue.lastRenderedReducer; |
| 3657 | if (lastRenderedReducer !== null) { |
| 3658 | let prevDispatcher = null; |
| 3659 | if (__DEV__) { |
| 3660 | prevDispatcher = ReactSharedInternals.H; |
| 3661 | ReactSharedInternals.H = InvalidNestedHooksDispatcherOnUpdateInDEV; |
| 3662 | } |
| 3663 | try { |
| 3664 | const currentState: S = (queue.lastRenderedState: any); |
| 3665 | const eagerState = lastRenderedReducer(currentState, action); |
| 3666 | // Stash the eagerly computed state, and the reducer used to compute |
| 3667 | // it, on the update object. If the reducer hasn't changed by the |
| 3668 | // time we enter the render phase, then the eager state can be used |
| 3669 | // without calling the reducer again. |
| 3670 | update.hasEagerState = true; |
| 3671 | update.eagerState = eagerState; |
| 3672 | if (is(eagerState, currentState)) { |
| 3673 | // Fast path. We can bail out without scheduling React to re-render. |
| 3674 | // It's still possible that we'll need to rebase this update later, |
| 3675 | // if the component re-renders for a different reason and by that |
| 3676 | // time the reducer has changed. |
| 3677 | // TODO: Do we still need to entangle transitions in this case? |
| 3678 | enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update); |
| 3679 | return false; |
| 3680 | } |
| 3681 | } catch (error) { |
| 3682 | // Suppress the error. It will throw again in the render phase. |
| 3683 | } finally { |
| 3684 | if (__DEV__) { |
| 3685 | ReactSharedInternals.H = prevDispatcher; |
| 3686 | } |
| 3687 | } |
| 3688 | } |
| 3689 | } |
| 3690 | |
| 3691 | const root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); |
| 3692 | if (root !== null) { |
| 3693 | scheduleUpdateOnFiber(root, fiber, lane); |
| 3694 | entangleTransitionUpdate(root, queue, lane); |
| 3695 | return true; |
| 3696 | } |
| 3697 | } |
| 3698 | return false; |
| 3699 | } |
| 3700 |
no test coverage detected