Notes

Creating a placeholder loading Component in React Native using Animated

Edit on GitHub

React Native & Expo
4 minutes

I’m creating a React Native component that shows as a placeholder for live data (in other words: loading boxes) and changing it’s color to indicate that stuff is loading..

Here’s how you go about doing that:

  1. Create a new Animated value, and give it the initial value.
1// set a value to be animated
2const currentColor = new Animated.Value(0)
  1. To change color you can use .interpolate() on the animated value you just created. Interpolate will take an array of input values inputRange, and another one of output values outputRange, and then map the values to each other. You can either do this interpolation inside your Animate function, or you can define it separately, which i did, like so:
1// interpolate color value
2const changeColor = currentColor.interpolate({
3  inputRange: [0, 1, 2],
4  outputRange: ['gainsboro', 'whitesmoke', 'gainsboro']
5})

What the code above would mean is that at my initial value of 0, the color would be gainsboro and when i move to 1 it’ll change to whitesmoke. Then i’m changing it back to gainsboro at 2 (because i want to loop the color change). If you set the toValue as 1 in the above code, it’ll only transition till whitesmoke and ignore what comes afterwards.

  1. Now, that i have the values defined, i’m going to setup my animation:
 1// define the looping animation
 2const animateColor = ()=> {
 3    Animated.loop(
 4      Animated.sequence([
 5        Animated.timing(currentColor, {
 6          toValue: 2, // the value in interpolated output range that you want to go to
 7          duration: 2000 // ms
 8        }),
 9      ])
10    ).start()
11  }

In my animation, i’ll loop a sequence of changes. Inside the sequence, i’m animating between different values (mapped to my colors above). Using the .timing() function, i’m changing the value i want to animate (defined as currentColor) over a period of 2000ms (i.e. 2sec) and going from the initial value of 0 to the interpolated value of 2 (using toValue).

The above two steps can also be combined like so:

  1. I’m starting the animation and saving the entire process as a function called animateColor. I’ll then pass that function to the useEffect() hook (i.e. the equivalent of componentDidMount())
1export default function App() {
2  useEffect(() => {
3    // start the animation to change background color
4    animateColor()
5  })
6  return (
7    // component goes here..
8  );
9}

In your component, when you’re setting styles, you’ll use the Animated.Value you defined in order to change color, in our case backgroundColor: changeColor

Here’s the full code:

 1import React, { useEffect } from 'react'
 2import { Animated, StyleSheet, View } from 'react-native'
 3
 4// set a value to be animated
 5const currentColor = new Animated.Value(0)
 6
 7// interpolate color value
 8const changeColor = currentColor.interpolate({
 9  inputRange: [0, 1, 2], // the values that the animation will transition from
10  outputRange: ['gainsboro', 'whitesmoke', 'gainsboro'] // values that are animating
11})
12
13// define the looping animation
14const animateColor = ()=> {
15    Animated.loop(
16      Animated.sequence([
17        Animated.timing(currentColor, {
18          toValue: 2, // the value in interpolated output range that you want to go to
19          duration: 2000 // ms
20        }),
21      ])
22    ).start()
23  }
24
25export default function App() {
26  useEffect(() => {
27    // start the animation to change background color
28    animateColor()
29  })
30  return (
31    <View style={styles.container}>
32      <Animated.View style={{ height: 150, width: 150, backgroundColor: changeColor, borderRadius: 8, margin: 8}}></Animated.View>
33    </View>
34  );
35}
36
37const styles = StyleSheet.create({
38  container: {
39    flex: 1,
40    backgroundColor: '#fff',
41    alignItems: 'center',
42    justifyContent: 'center',
43  },
44});

Notes

  • The above code is now in a good place to be used as a starting point. If you want to use rgba values, you may have to look into hex-to-rgba
  • The entire thing could just be a CSS animation as well, look into that. I mean, we’re only changing the background color? Answer: In vanilla React Native you can not use CSS animations. The Stylesheet properties in React Native are pretty limited. You can find a list of all supported properties here
  • But maybe we can do CSS animations using styled-components?

Animating SVGs

Can i use SVGs as placeholder? Sure. you’d have to use another library (e.g. react-native-svg)to add SVG support to React Native, and then you’d have to create a custom animated components using createAnimatedComponent to be able to animate an <Svg> component

See example here

1import { Path } from "react-native-svg";
2const AnimatedPath = Animated.createAnimatedComponent(Path);

See Animating SVG in React Native