useTransition API rewrite
Author: joshuaellisCreated Jun 11, 2026Updated Jun 11, 2026
Labelskind: requestarea: corerelease: major
A clear and concise description of what the feature is
Rewrite useTransition (packages/core/src/hooks/useTransition.tsx) around a declarative enter/leave model — presence made explicit, "obvious on first read" — without the render-prop bookkeeping it has today:
// today — you index into a render prop, and it's unclear where `item` comes from
const transitions = useTransition(items, {
keys: item => item.id,
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
})
return transitions((style, item) => (
<animated.div style={style}>{item.text}</animated.div>
))Would also subsume #2136 (per-property configs should fall out of the new model rather than be bolted on).
Why should this feature be included?
useTransition is the library's most-reported source of confusion — the same friction recurs across years:
- #665 (2019) — the API was called "a little weird": users "see
itemdown in the view section and don't know where it comes from." - #1281 (2021) — confusion over where
statefits once the API takesitems. - #1711 (discussion) — "how do I make it wait so the
leavetransition can have an effect?" — exit timing isn't discoverable.
Related issues
- #1955 —
<Presence>component; the enter/exit primitive a cleaneruseTransitionunlocks. - #1628 — persisting/animating components across route changes; a real-world presence use case (its shared-layout half maps to
layoutId, tracked separately).
Scope / non-goals
- The exact new API shape is what this issue is to settle.
- It must keep react-spring's model: you own the springs and the new API orchestrates them. Presence must not become props on
animated.*that create/own springs internally — that inverts the model (see the reasoning on #1826).
Source: pmndrs/react-spring