useAnimationState
useAnimationState is a React hook for driving animations. It's an alternative to the animate prop.
It's useful when you:
- want the best performance on native,
- know your different animation states ahead of time, and
- don't mind using a hook
When to use this#
useAnimatedState lets you control your animation state based on static variants. It is the most performant way to drive animations, since it lives mutates shared values directly, instead of relying on JS state changes. You probably won't notice a performance difference, but you can keep it in your back pocket.
When using this hook, your animations are static, meaning they have to be known ahead of time. You can change the state by using transitionTo, but re-rendering your component does not update your variants.
Basic Usage#
Import#
Moti exports typical react-native components, such as View, Text, etc.
Define your state#
Pass state to your Moti component#
Create your animationState, and pass it as your moti component's state prop.
Update state with transitionTo#
To change the animation variant, use the transitionTo function.
You can also transition based on the current animation state, similar to setState from React's useState hook:
The function prop pattern isn't actually necessary, since updates are synchronous, unlike setState, which makes asynchronous updates. But I added this API because I'm used to it from setState and enjoy it.
It's worth noting that animationState.transitionTo will not trigger re-renders, so just keep that in mind.
Read the current state#
You could also read the current animation state, and use that to drive the next transiton, if you prefer:
A full example#
Mount Animations#
If both from and to are set, then it will transition from one to the other on the component's initial mount. If only from is set, this will be the initial state.
If you don't want mount animations, give your variants different names.
Don't destructure#
As a rule of thumb, don't destructure the animation state.
Why?#
useAnimationState returns an object with a stable reference, but destructuring .current does not guarantee a stable reference.
You don't have to follow that suggestion if you don't want to. But I recommend it to prevent unintended consequences of triggering effects when these are used in dependency arrays.
If you aren't using the animator in a dependency array anywhere, then you can ignore this suggestion. But I treat it as a rule of thumb to keep things simpler.
Technically, it's fine if you do this with transitionTo. It's current you'll want to watch out for, since its reference will change, without triggering re-renders. This functions similar to useRef.
API#
Arguments#
variants(required)- an object with variants specifying your different static styles.
- to achieve mount animations, pass a
toandfromvariant here.
config- Optionally define your
fromandtovariant keys.
- Optionally define your
If you need to rename to or from, do it like so:
By default, similar to react-spring, you can pass a to and a from variant. from will always be the initial state, assuming you pass from. It is not required, though.
If, for some reason, you really don't want to use from and to as your props, you can pass a second argument object with from/to keys that rename them.
Returns#
currentA synchronous way to read the current animation state. Returns the name of the current state (for example,to).transitionTo(nextVariant)A function that lets you update the state.
You can pass the next state directly to it: `animationState.transitionTo('open')
Or you can pass it a function:
Static animations only#
Unlike react-spring's useSpring, useAnimationState will not update your animation state if you change its style values.
useAnimationState should only be used for static variants, meaning the different potential states you'll be animating to will be known ahead of time.
Any dynamic animations should be used with a component's animate prop directly.
For most cases, this is fine, but just keep that in mind. If you need styles that automatically update based on React's state, use a component's animate prop instead of this hook.
...ok, but#
Now that I got those warnings out of the way, I'll clarify: technically, you can use dynamic variables in this hook. However, only calling transitionTo will change the actual style. So if you use dynamic variables, just know that they won't apply to your styles until you call transitionTo.