Let’s Get Moving: An Introduction to React Native Animations — Part 1

Shane Boyar
4 min readMar 4, 2019

--

When I first got into writing apps in React Native, I had visions of modern and dynamic layouts with awesome animations. Sometimes, however, you get so fixated in making the dang thing work the way you want to you just never get around to figuring out how to get the proverbial animated icing on the cake.

In this series I will introduce the basic concepts I’ve picked up on how to get your App moving in the ways you want to as quickly as possible.

Caveat: This article assumes you know the basics of react / react-native and have the react-native cli tools installed. For more information on that you can read the docs here.

Part One: LayoutAnimation

Open up your terminal and let’s get started with a basic app.

react-native init Animations
cd Animations
react-native run-ios

If you’re still with me, you should see something like this:

Most of what we’re going to do here is going to happen inside App.js for simplicities sake. So open that up in your browser of choice and clear out everything except the basic boilerplate. Import Image from 'react-native’ and drop one inside the container view. For this example I’m using this png of Jake from Adventure Time and just placing it in the root of the project. I’ve also added some top and bottom padding to the container to avoid the notch and menu bar at the bottom:

// App.jsimport React, { Component } from "react";
import { StyleSheet, Image, View } from "react-native";
import jake from "./jake.png";
export default class App extends Component { render() {
return (
<View style={styles.container}>
<Image source={jake} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
paddingTop: 64,
paddingBottom: 32
}
});

LayoutAnimation is React Native’s most basic animation system. Anytime the view is going to re-render, causing elements to change their position/size/rotation/etc, running LayoutAnimation.[easingFunction]before the re-render will cause those differences in layout data to be animated.

Let’s assign the vertical positioning rule on our container (which currently only includes Jake) to a piece of state in our component:

// App.js{...}class App extends Component {
constructor(props) {
super(props);
this.state = { position: "flex-start" };
}
render() {
return (
<View style={[styles.container, { justifyContent: this.state.position }]}>
<Image source={jake} />
</View>
);
}
}
{...}

Now lets just create some buttons that update that position.
Import Button from react-native and add some to your render method:

// App.jsrender() {
return (
<View style={[styles.container, { justifyContent: this.state.position }]}>
<Image source={jake} />
<View style={styles.buttonsContainer}>
<Button style={styles.button} title="Top" />
<Button style={styles.button} title="Middle" />
<Button style={styles.button} title="Bottom" />
</View>
</View>
)
}
{...}
buttonsContainer: {
flexDirection: "row",
justifyContent: "space-evenly",
position: "absolute",
bottom: 16,
width: "100%"
},
button: {
width: 100
}
{...}

Now we will create a method to change the `justifyContent` value on the icon and apply it to the buttons we created with the appropriate argument:

// App.js{...}changePosition = position => {
this.setState({
position
});
};
{...}<View style={styles.buttonsContainer}>
<Button
style={styles.button}
title="Top"
onPress={() => this.changePosition("flex-start")}
/>
<Button
style={styles.button}
title="Middle"
onPress={() => this.changePosition("center")}
/>
<Button
style={styles.button}
title="Bottom"
onPress={() => this.changePosition("flex-end")}
/>
</View>
{...}

Our buttons now instantly change the positioning of the icon.

Now, since this is a simple layout change, and the only thing really going on with these re-renders, it’s a perfect candidate for using RN’s LayoutAnimation API. Simply import LayoutAnimation from "react-native"and run it before setting your new state.

Note that in order to get this to work on Android you need to set the following flags via UIManager which is also imported from react-native: UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);

// App.jsUIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);{...}changePosition = position => {
LayoutAnimation.spring();
this.setState({
position
});
};
{...}

LayoutAnimation provides us with three easing presets spring , linear , and easeInEaseOut . Custom configurations can be make, but I’m not going into that here. You can read more about what’s happening under the hood with LayoutAnimation here.

LayoutAnimation.spring() is a shortcut for the more verbose LayoutAnimation.configureNext(LayoutAnimation.Presets.spring) .

Refresh your app, and now you should see Jake move with a pleasant springy movement!

This gif runs quite a bit slower than your actual animation will.

The final code can be found here.

Hopefully this was a pretty painless introduction to getting things moving in your React Native apps. In the next part we will go into more granular control over our animations.

📝 Read this story later in Journal.

🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: Get the noteworthy newsletter >

--

--

Shane Boyar

Shane is a software engineer, home-brewer, bread baker, and writer living in Richmond, VA. Currently writing code @ RTSLabs