Next, animate your interactions:
MotiPressable component lets you animate based on
hovered interactions, without triggering any re-renders.
The usage is very similar to
The two differences are 1) you use the
animate prop rather than
style, and 2) the function you pass must be a
worklet, resulting in faster performance and a better developer experience.
MotiPressable relies on the native thread when tracking interactions.
Check out these tweets from Fernando Rojo for more context:
- From Moti's API to MotiPressable
- Remaking BeatGig's web dropdown menu with moti interactions
- Animating children of a Pressable component without re-renders
Make sure you've also followed the Installation steps for
moti. If you're using a version of
moti that is older than
0.14.x, upgrade here:
And if you're using any other Moti components, upgrade those too:
A common use-case of a component like
Pressable is styling children based on the animation state.
moti, you might do this with the React Native
Moti takes a different approach to improve performance and composition.
Rather than using React state to track the interaction, Moti uses Reanimated shared values with React Native Gesture Handler.
As a result, Moti's interactions trigger zero re-renders, and all animations are handled on the native thread.
Let's see what the above example might look like with Moti.
MotiPressable. Next, remove the function child, and instead pass a component directly. Let's call it
Then, in the
Child component, we can access the parent's interaction state with
useMotiPressable also optionally takes a unique
id as its first argument. This lets you access a specific parent pressable's interaction.
For example, say you have a
list component at the root, and you want to access its state:
Notice that the
MotiPressable component now has an
id="list" prop. This tells all of its children that it can be uniquely referred to as
By default, the
useMotiPressable would access the interaction state of its closest
MotiPressable parent. That default behavior doesn't work for this case, since we want to animate based on the top-level list component.
Child component, pass
list as the first argument to
That's it. Now,
useMotiPressable will return animate based on the interaction state of the outer-most
In the previous section, we saw how to access a unique parent's interaction state. But what if we want to combine the interaction states of multiple components for more complex animations?
That's easy too. Our previous example looked like this:
Let's add a unique
id prop to each
MotiPressable item that's rendered in the list, called
Let's also pass the
id as a prop to the
Child component can call
useMotiPressables instead of
Say we want to make all items fade away when you hover over the list, except for the actual item you're hovering.
Let's say you want to update a child component's props based on a parent's interaction state.
For example, you have a dropdown menu whose
pointerEvents should be
none when its container isn't hovered.
You can also pass a TypeScript generic to
useMotiPressableAnimatedProps relies on
useAnimatedProps under the hood.
animatedPropscannot be used with
animateon the same prop on Web. If you need to do both, please split your usage into two components; one that receives the
animateprop, and another that receives
animateProps. This is a reanimated limitation.
A rare but available use-case is
As the name implies, this lets you access the shared value state of a parent pressable.
If you're passing a unique
id prop to your pressable, you can also isolate this hook to that pressable.
Say the parent pressable has
id="list", and you want to isolate this hook to the
Then, in the
It returns an
Animated.DerivedValue. You can also type it with a generic:
Just like any derived value, you can read the value it returns with
By default, this component should have better performance than the native
Pressable. It triggers zero re-renders, and all animations are run on the native thread.
If your component re-renders often, consider wrapping your hook with
useCallback to improve performance:
For all the hooks provided, you can also pass a dependency array to improve performance. It works just like the dependency array for
useMemo, and it's always the last argument for any of the pressable hooks.
MotiPressable provides first-class support for Web, including
Please note that Reanimated 2 uses JS animations on Web. That said,
MotiPressable still doesn't trigger re-renders on web.