Moti vs. Reanimated
Should you use moti
or react-native-reanimated
? I get this question often, so let's break it down.
First off, Moti uses Reanimated under the hood. This means that Moti's components can do anything a Reanimated can, with additional features.
#
Simple comparisonLet's start by comparing a simple example. Take this Moti component:
Let's implement the same thing with Reanimated:
Under the hood, Moti builds this useAnimatedStyle
hook for you, with a number of additional features.
The benefit of using Reanimated directly is often more seen with imperative usage, which I'll touch on later. But for declarative styles, the Moti API usually offers what you need.
#
Reanimated props in MotiLet's rewrite the Reanimated example from above, this time using MotiView
instead of Animated.View
.
Turns out, that's completely valid. After all, MotiView
is a layer on top of Animated.View
. If it works with Reanimated, then it works with Moti.
#
Shared ValuesReanimated shared values let you power animations at 60 FPS without triggering any re-renders. This offers great performance.
When using useAnimationState
or useDynamicAnimation
from Moti, you are using a Reanimated shared value under the hood to power animations.
animate
prop#
To use Reanimated shared values with Moti, you can pass useDerivedValue
to the animate
prop. This allows the animate
prop to be fully reactive to shared value changes, without requiring re-renders.
The values in animate
will automatically transition. You don't need to use withTiming
/withSpring
functions. Instead, you can customize transitions with the transition
prop.
#
Derived valuesYou can also use derived values with Moti. Here, we'll derive translateY
from isValid
. We'll then use it inside of the animate
prop's derived value.
#
Custom transitionsYou can also pass useDerivedValue
to your transition
prop to use Reanimated values.
#
GesturesFor animating based on simple interactions, such as hovered and pressed states, I recommend using moti/interactions
.
However, Moti will also work with react-native-gesture-handler
. You can use useSharedValue
as shown above to track gestures.
Or, you can use a Moti hook:
#
When should I use Reanimated directly?If you find yourself hacking together something really complicated with Moti, it might be worth trying out Reanimated directly. For complex gestures that require granular control, Reanimated is likely the way to go.
#
Imperative controlReanimated offers a cool way of using an imperative-style API:
If you're chaining together multiple animations with complex things done in each step, Reanimated might be the way to go.
Moti lets you listen to changes in animations with the onDidAnimate
prop, but it's harder to know which step of the animation was fired.