Breaking Changes
This page is all about breaking changes between v8.x and v9.x. Get ready to upgrade!
The useTransition hook
The new useTransition is used like this:
// 1. Provide items and propsconst transition = useTransition(items, props)// 2. Map the items into a fragmentconst fragment = transition((style, item) => {// 3. Render each itemreturn <a.div style={style}>{item}</a.div>})
The transition function
On this page, the transition function returned by useTransition is
referred to as the TransitionFn (its type name in TypeScript).
It accepts a callback that receives four arguments: the animated values,
the item, the Transition object, and the sibling position.
It returns a React fragment containing every element returned by your
callback. As you might assume, elements in the middle of their leave
animation need to remain mounted.
All elements in the fragment are guaranteed to have a key prop, whether or
not you define one explicitly. Unkeyed elements will use the ctrl.id from
their Transition object.
Transition objects
For every unique item key, there exists a Transition object. The only time
you have access to a Transition object is when it's passed as the 3rd argument
of your TransitionFn callback.
// The `t` argument is a Transition object.// The `i` argument is the sibling position.const elems = transition((style, item, t, i) => (<a.div style={style}>{t.phase}</a.div>))
Transition keys
Every Transition object has a unique key that identifies it. You have the
option of defining explicit keys or letting the "item" (the value represented
by the Transition object) be its own key.
To define explicit keys, you must define the keys prop in your useTransition
props. For example, when using an items array, the new keys prop can be:
- an array of keys
- or a mapping function that returns a key for any item given to it.
useTransition(items, {// Using a functionkeys: item => item.key,// Using an array created by lodash.mapkeys: _.map(items, 'key'),})
⚠️ You must use explicit keys for any item that is an immutable object.
Using explicit keys for mutable objects is unnecessary. 🥳
The key prop
If you're passing a single item to useTransition, you have the option of
passing a single key as the key prop.
useTransition(item, {key: item.key,})
The expires prop
The expires prop lets you control when removed items are unmounted (after
their leave animation has finished). By default, unmounting is postponed
until the next render or until all transitions are resting.
When true or <= 0, the default behavior is used.
When false, items are never unmounted.
When > 0, this prop is used in a setTimeout call that forces a
rerender if the component that called useTransition doesn't rerender
on its own after an item's leave animation is finished.
Finally, the expires prop can be a function that receives an item and returns any of
the values mentioned above.
The ref prop
Pass a ref as the ref prop for access to the ref API.
const ref = useRef()useTransition(items, {ref,from: { opacity: 0 },enter: { opacity: 1 },leave: { opacity: 0 },})useEffect(() => {ref.current.start()})
The TransitionHandle object in ref.current has an almost identical
API to what useSprings has.
The sort prop
The sort prop is a function that takes two items, returns -1 when
the 1st item should appear first, and returns 1 when the 2nd item should.
It's a useful shortcut for slicing and sorting your items array before passing
it to the useTransition hook.
// v8useTransition(items.slice().sort(props.sort), null, props)// v9useTransition(items, {sort: (a, b) => { ... },...props})
Other changes
Here are the breaking changes in useTransition without their own section.
- The - resetprop now prefers the- initialprop over the- fromprop.
- The - uniqueprop was removed. Unique mode is now the default behavior.
- The - lazyprop was removed (in favor of the- expiresprop). Lazy mode is now the default behavior.
- The - onDestroyedprop was removed.
- The - orderprop was removed.
The onFrame prop
This prop has been renamed to onChange, because it's not necessarily called
from within a requestAnimationFrame callback.
For example, the onChange prop is called when you call the set method of an
animated value.
The to prop
When using an async to function inside a component that renders frequently,
you'll need to memoize your to function to prevent an unintended restart.
One solution is to use the useCallback hook.
useSpring({to: useCallback(async animate => { ... }, []),})
Another solution is to pass a props function.
useSpring(() => ({to: async animate => { ... },}))
The from prop
The from prop now behaves differently in imperative updates. When defined,
it implies the reset prop is true. Previously, the from prop would
not affect the animation unless reset: true was explicitly defined.
To prevent this behavior, you can define reset: false.
The example above uses the new SpringValue API.
The interpolate function
This function is now the to function.
import { to } from 'react-spring'const { x, y } = useSpring({from: { x: 0, y: 0 },})// Combine two animated valuesto([x, y], (x, y) => x / y)
Globals API
Global configuration has been improved.
import { colorNames, createStringInterpolator } from './globals'// v8import * as Globals from 'react-spring/animated/Globals'Globals.injectDefaultElement('div')Globals.injectStringInterpolator(createStringInterpolator)Globals.injectColorNames(colorNames)// v9import { Globals } from 'react-spring'Globals.assign({defaultElement: 'div',createStringInterpolator,colorNames,})
The Controller class
Unless you've been using new Controller() or have been accessing the controllers
property off the ref API, these changes won't affect you.
- The - interpolatemethod is now the- tomethod.
- The - stopmethod no longer has an optional- finishedargument. Instead, it accepts zero or more keys to specifically stop animating.
- The - pausemethod was removed. This method will be restored once the pausing feature is ready.
- The - destroymethod was renamed to- dispose.
- Most properties have been either renamed or removed.