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
reset
prop now prefers theinitial
prop over thefrom
prop.The
unique
prop was removed. Unique mode is now the default behavior.The
lazy
prop was removed (in favor of theexpires
prop). Lazy mode is now the default behavior.The
onDestroyed
prop was removed.The
order
prop 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
interpolate
method is now theto
method.The
stop
method no longer has an optionalfinished
argument. Instead, it accepts zero or more keys to specifically stop animating.The
pause
method was removed. This method will be restored once the pausing feature is ready.The
destroy
method was renamed todispose
.Most properties have been either renamed or removed.