-
Notifications
You must be signed in to change notification settings - Fork 49k
Description
The order of returned values in useTransition is opposite to what I consider to be an established pattern of [value, function]
.
Current: const [startTransition, isPending] = useTransition()
.
Expected: const [isPending, startTransition] = useTransition()
.
Also fine: const { startTransition, isPending } = useTransition()
.
Rationale
The order is in my opinion inconsistent with other hooks, built-in and community hooks, and this inconsistency is somewhat bothersome on the aesthetic level.
Users without tooling support (TypeScript et al) will see Uncaught TypeError: startTransition is not a function
error whenever they get the order wrong.
Having this insonsistency risks reducing the strength of the convention in the community, making hooks less convenient to use overall.
Built-in hooks
const [state, setState] = useState();
const [state, dispatch] = useReducer();
const [startTransition, isPending] = useTransition();
Community examples
I have done a quick overview of positional returned values from hooks in the community. Hooks that use [value, function]
pattern:
useImmer, streamich/react-use (useTimeout, useSessionStorage, useLockBodyScroll, useLocalStorage, useToggle) bdbch/react-localstorage, rehooks/local-storage, react-rekindle/use-request.
Hooks that use [function, value]
pattern: none.
Is second value optional?
One could argue that, unlike with other examples, useTransition does not require the user to care about the isPending
value. However, not using isPending creates a poor UX that the extisting React docs explicitly call out as a problem. We’re supposed to care about isPending. (docs).
Besides, even with corrected value order, the user can still ignore isPending at a low cost of an explicit parameter skip (const [, startTransition] = useTransition()
).
Can we return an object?
useState returns a list for convenient aliasing:
const [color, setColor] = useState();
const [position, setPosition] = useState();
For hooks that a single component uses only once the benefit is significantly reduced and the community often chooses to return an object with named values instead. This removes the problem of getting positioned values incorrectly and is more inline with the broader JavaScript ecosystem.
I am speculating here, but it seems like a component will often only have one transition, like the Button example in the docs. In that case it seems beneficial to return named values and reserve the positioned return values for cases where it really matters.