Skip to content

Commit

Permalink
Refactor host transitions to call useState directly
Browse files Browse the repository at this point in the history
The useTransition hook is a thin wrapper around useState; all it really
does it map over the return value. We going to change the return value
for form actions, anyway, so we should call useState directly instead.
  • Loading branch information
acdlite committed Apr 26, 2023
1 parent 6e2db5f commit 3b2f716
Showing 1 changed file with 11 additions and 22 deletions.
33 changes: 11 additions & 22 deletions packages/react-reconciler/src/ReactFiberHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,11 @@ export function TransitionAwareHostComponent(): boolean {
return false;
}
const dispatcher = ReactCurrentDispatcher.current;
const [isPending] = dispatcher.useTransition();
return isPending;
const [booleanOrThenable] = dispatcher.useState();
return typeof booleanOrThenable === 'boolean'
? booleanOrThenable
: // This will suspend until the async action scope has finished.
useThenable(booleanOrThenable);
}

export function checkDidRenderIdHook(): boolean {
Expand Down Expand Up @@ -2545,8 +2548,8 @@ export function startHostTransition<F>(
// it was stateful all along so we can reuse most of the implementation
// for function components and useTransition.
//
// Create the initial hooks used by useTransition. This is essentially an
// inlined version of mountTransition.
// Create the state hook used by TransitionAwareHostComponent. This is
// essentially an inlined version of mountState.
const queue: UpdateQueue<
Thenable<boolean> | boolean,
Thenable<boolean> | boolean,
Expand All @@ -2569,32 +2572,18 @@ export function startHostTransition<F>(
(dispatchSetState.bind(null, formFiber, queue): any);
setPending = queue.dispatch = dispatch;

// TODO: The only reason this second hook exists is to save a reference to
// the `dispatch` function. But we already store this on the state hook. So
// we can cheat and read it from there. Need to make this change to the
// regular `useTransition` implementation, too.
const transitionHook: Hook = {
memoizedState: dispatch,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

stateHook.next = transitionHook;

// Add the initial list of hooks to both fiber alternates. The idea is that
// the fiber had these hooks all along.
// Add the state hook to both fiber alternates. The idea is that the fiber
// had this hook all along.
formFiber.memoizedState = stateHook;
const alternate = formFiber.alternate;
if (alternate !== null) {
alternate.memoizedState = stateHook;
}
} else {
// This fiber was already upgraded to be stateful.
const transitionHook: Hook = formFiber.memoizedState.next;
const stateHook: Hook = formFiber.memoizedState;
const dispatch: (Thenable<boolean> | boolean) => void =
transitionHook.memoizedState;
stateHook.queue.dispatch;
setPending = dispatch;
}

Expand Down

0 comments on commit 3b2f716

Please sign in to comment.