The building blocks of React Native animations
08 Mar 2017
It is hard to imagine a mobile app that does not involve animations. Whereas on the web, animations are typically pretty simple, if existent at all — a new page can replace the existing one; mobile applications demand a different level of attention.
CSS3 has a relatively simple API that can let you make some pretty basic animations. But you don't have that on React Native. It probably wouldn't be enough either way.
So, if you work with React Native, and need to implement meaningful animations, what do you need to know?
React Native has Animated
, but it does look scary... at least at first.
So here are three "clusters of things" or "blocks," if you will, that I think of when working with animations.
Block 0: Need for change
Animations represent a transition from one state to another:
- From being hidden to being shown.
- From a circle to a square.
Think what needs to be shown both before and after an animation.
Consider how the transition should go, and think of which styles need to change for that:
- Should a thing appear by changing opacity, or should it "fall down" from the top?
- Should a circle just morph into a square, or should it become a triangle mid-way?
Block 1: Visual state aka Animated.Value
Logically, some component can be either shown or hidden — true
or false
; it can't really be somewhere halfway.
In your state, the status of whether something is shown will be either true
or false
.
In a good UI, things aren't hidden right now and suddenly shown the next moment. They "appear" gradually, to help the user make sense of the interface.
So it's clear the visual state can be somewhere between just true
and false
.
How come?
We can introduce another variable to represent the visual state of the slider. We want it to be a number because no matter what the logical state is, numbers allow us to represent the states in-between.
this._shown = new Animated.Value(0);
While the logical state can be binary (i.e. either true
or false
, 1
or 0
), the visual state is floating-point.
Block 2: Transitions aka Animated.timing
Say some component is hidden: it means the logical state of its visibility will be false
, and visual will be 0.0
too.
But what happens as we want to show the component?
The logical state should immediately become a true
, whereas the visual state should go to 0.1
, 0.2
, ... and all the way to 1.0
.
For that, we need a way to tell the visual state to go to 1.0
.
And there is. Actually, a few.
The simplest way to do it is basically:
Animated.timing(this._shown, {
toValue: 1,
duration: 300,
}).start();
Here, we tell Animated
to change _shown
up to 1.0
in the span of 300ms.
There are other transitions and ways to orchestrate multiple transitions, but we can keep it to Animated.timing
for now.
Block 3: The Pixels aka Animated.View
and interpolate
Our transitions of _shown
between 0.0
and 1.0
are all for nothing is we can't see them. So how can we see them?
We should somehow be able to use _shown
to set the opacity
of the child component.
Suppose we had this code before we attempting with animations:
<View style={{ opacity: this.state.shown ? 1 : 0 }}>
<SomeComponent />
</View>
We were setting the opacity
to 0
when hidden, and 1
when shown.
Can we use this Animated.Value
we have, _shown
, to animate it between 0 and 1?
Animate the styles
We can use any animated value to influence the style.
We just have to change View
for Animated.View
, and now we can have this:
const opacity = this._shown; // This is an Animated.Value
<Animated.View style={{ opacity: opacity }}>
<SomeComponent />
</Animated.View>;
Isn't this a post on ANIMATIONS? How come there hasn't been a single picture up until now?
One more thing: interpolation
This may sound like a scary word, but the idea is pretty simple: it allows us to keep the visual state between 0 and 1, but kind of "map" to something else, should we need to.
Say instead of just making a child component appear; we wanted also to make it "fall down" from the top a bit. And we would do that by putting the hidden component 40px higher, and animate to its normal position as we make it visible.
We can "map" our 0-to-1 values to minus 40-to-0 using a simple interpolate
call:
const top = this._shown.interpolate({
inputRange: [0, 1],
outputRange: [-40, 0],
});
This will create a new animated value that will be between -40 and 0.
In other words, it will be -40
when _shown
is 0
, it will be -20
when _shown
is 0.5
, and it will be 0
when _shown
is 1.0
.
Dark secret: you can also output colors and degrees from interpolate
.
Recap
- Visual state is numeric, as it needs to be able to represent a transition from one style to another.
Animated.Value
allows representing numeric visual state.Animated.timing
can be used to transition anAnimated.Value
to another number.Animated.Value
can be used for styling if you swapView
withAnimated.View
.- Interpolations allow to "map" one range of
Animated.Value
into another: e.g. go from "between 0 and 1" to "between 5 and 25", or even to "between green and black."
To help, I've prepared a cheatsheet featuring the building blocks along with quick and to-the-point descriptions:

Exclusive bonus: Download the free Building blocks of React Native animations cheatsheet that you can print out or have handy on your desktop.
I'll email it to you right away so you can access it from anywhere!No spam. I will occasionally send you my posts about JavaScript and React.
Resources
This is meant as a quick introduction to the animation primitives in React Native to give a basic idea. Here are additional useful resources that go deeper:
- A fantastic Animate React Native UI Elements course on Egghead by Jason Brown — this is the best of the best
- Official React Native docs on animations
- Official
Animated
reference - My post on animating appearance and disappearance with React Native
- My post + screencast on making a floating-label input
- 4 places to draw inspiration from for practicing React Native