Create Animated React Apps With React Spring

Publikováno: 5.12.2018

One thing that is pivotal to creating great interactive web applications is animations. Animations add life to your applications and improve the overall user experience.

In this tutorial, w...

Celý článek

One thing that is pivotal to creating great interactive web applications is animations. Animations add life to your applications and improve the overall user experience.

In this tutorial, we'll be looking at how to create simple yet lovely animations in your React apps using an npm package called react-spring, specifically, the Spring component of the package.

React Spring is a great animation package that has been endorsed by some of the React core team including Dan Abramov, and is generally considered one of the best animation packages for React apps out there. It utilises spring like physics in its core animations making it easy to configure. In this tutorial we'll be focused on the Spring component which is one of react-spring's easier to use and more flexible components.

With Spring we are able to:

  • Manipulate values(numbers)of any sort from measurement units to actual data.

  • Manipulate HTML attributes

  • Manipulate SVG paths

  • Adjust CSS

And much more!

Springs are cumulative, meaning they'll remember all values passed to them. Let's look at how we can get started with Springs, complete with an example making use of the newly announced React Hooks.

Examples

What We'll Build

We'll be building a simple sliding and fading animation to show you how easily you can achieve animations.

https://codesandbox.io/s/github/austinroy/react-spring-demo

Setting Up

We'll be setting up our React environment with create-react-app which will also generate some boilerplate code that will allow us to get started. To install it run

npm install -g create-react-app

Now you can use it to create your app. Run:

create-react-app react-spring-demo

A folder named react-spring-demo will be created containing our project. Cd into that directory and install our primary dependency, the react-spring package by running:

yarn add react-spring

You will notice we're using yarn as the package manager for this project as it is the default package manager used by create-react-app. Make sure to have yarn installed by running

npm install -g yarn

We are now set up to go, let's create our first animated page.

Animating Styles

Spring can be used to animate styles, to do this, we'll use it to animate the transition into a newly loaded page. To do this we'll wrap the jsx context of App.js in a Spring component.

The Spring component will take two props, from and to which represents the values to be interpolated by our animation.

In our case we want to create the effect of a page dropping down from above and fading in. To do this, we'll set the initial top margin of the page elements to be a negative value and bring it to 0 during the animation creating a dropping motion. To create the fade in effect, we'll set the initial value of the opacity to 0 and bring that value to 1 at the end of the animation. Luckily for us, the boilerplate generated by create-react-app has the perfect background to show this effect at work so we won't need to change it for now.

This is what it will look like in our App.js file:

App.js

//
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Spring  } from 'react-spring';

class App extends Component {
  render() {
    return (

        <Spring from={{ opacity: 0, marginTop: -1000 }} to={{ opacity: 1, marginTop: 0 }}>
          { props => (
            <div  className="App" style={ props }>
              <div >
                <header className="App-header" >
                    <img src={logo} className="App-logo" alt="logo" />
                    <p>
                      Edit <code>src/App.js</code> and save to reload.
                    </p>
                      <a
                        className="App-link"
                        href="https://reactjs.org"
                        target="_blank"
                        rel="noopener noreferrer"
                      >
                      Learn React
                    </a>
                  </header>
                </div>
              </div>
            )
          }
        </Spring>
    );
  }
}

export default App;

Now fire up your application by running this command.

yarn start

Your browser will open up and you should see the page load with the contents having the desired drop and fade in animations.

Nice, isn't it? You can use spring to create any even more style animations adjusting a variety of styles. It is however advised to stick to animating opacity and translations to keep your app light.

Animating innerText

Animating styles is great but we can also use Spring to animate the value of contents shown on the screen. To show this, we'll be creating a counter that starts at 0 and ends at 10 using Spring. As expected, from will hold our initial value and to will hold the final value to be displayed.

Under the src directory, create a folder called components and in it a file called Counter.jsx. Add the following code to Countrt.jsx :

//src/Counter.jsx
import React from 'react';
import { Spring } from'react-spring';

const counter = () => (
    <Spring
        from={{ number: 0 }}
        to={{ number: 10 }}
       {props => <div>{props.number.toFixed()}</div>}
    </Spring>
)

export default counter;

Now import our counter into App.js and add it under the header element to render it in our app.

//App.js
...
import Counter from './components/Counter';

class App extends Component {
  render() {
    return (

        <Spring from={{ opacity: 0, marginTop: -1000 }} to={{ opacity: 1, marginTop: 0 }}>
          { props => (
            <div  className="App" style={ props }>
              <div >
                <header className="App-header" >
                    <img src={logo} className="App-logo" alt="logo" />
                    <p>
                      Edit <code>src/App.js</code> and save to reload.
                    </p>
                      <a
                        className="App-link"
                        href="https://reactjs.org"
                        target="_blank"
                        rel="noopener noreferrer"
                      >
                      Learn React
                    </a>
                    <Counter />
                  </header>
                </div>
              </div>
            )
          }
        </Spring>
    );
  }
}

export default App;

Opening up your browser you will notice the counter just under the Learn React text, like this: Just one catch, our animation is happening so soon that we are missing most of it as it occurs while our initial page is animating into visibility. Luckily, we can delay our animation by adding a delay prop which will be equated to a value in milliseconds, this is the amount of time our animation will wait before starting. Adding a 1 second delay, the counter function will now look like this:

const counter = () => (
    <Spring
        from={{ number: 0 }}
        to={{ number: 10 }}
        delay= '1000'>
        {props => <div>{props.number.toFixed()}</div>}
    </Spring>
)

Checking the browser, the counter now starts after the page animations are finished. Another method we can use to add this delay is through the config prop which we'll come to when discussing the Spring configurations shortly.

Spring config

As mentioned before,Springs are physics based. This means we don't have to manually deal with durations and curves. This is great as it takes away some of the heavy math we may have to cover. However, we can still adjust the behaviour of our Spring by tweaking it's tension, friction, delays, mass and other behaviour through the config prop.

Don't wish to deal with this but still want to adjust your animations? Don't worry, react-spring comes with some inbuilt presets that we can use to tweak our Springs. All we have to do is import config from the react-spring package and feed them to the config prop of the Spring. Before we get confused about which config is which, let's take a look at an example.

import React from 'react';
import { Spring, config } from'react-spring';

const counter = () => (
    <Spring
        from={{ number: 0 }}
        to={{ number: 10 }}
        delay= '1000'
        config = { config.molasses }>
        {props => <div>{props.number.toFixed()}</div>}
    </Spring>
)

export default counter;

In the example above, we've used the molasses preset which is a high tension, high friction preset provided by react-spring . The presets typically define the tension and friction properties of out Spring. These presets include molasses, default, slow, stiff and wobbly.

While the presets only define the tension and friction, you can manually configure other properties of the Spring animation which include but are not limited to delay, mass, velocity and duration. For a full list of properties you can configure, along with other options that can be passed as props, check out this page.

Usage With Hooks

The React team recently introduced React Hooks, this allows us to create functional components that can permanently store data and cause effects, basically adding state to functional components. Hooks are currently only available in React 16.7 alpha as we await a stable release. To use hooks you will need to upgrade to the 16.7 alpha versions of react and react-dom.

To do this, run the following commands:

yarn remove react-dom && yarn add react-dom@16.7.0-alpha.0

yarn remove react && yarn add react@16.7.0-alpha.0

We can use hooks out of the box with react-spring which exports a hook called useSpring. This hook allows us to define and update data and will generally consist of the same values you would pass as props and useSpring will turn it into animated data. To showcase this, let's look at how we can have more text rendered after our previous animations are done animating.

Here's how we can do that, let's create a new component file called Hooks.jsx and add the following code.

//Hooks.jsx
import React from 'react';
import { useSpring, animated } from 'react-spring';

const HookedComponent = () => {
    const [props] = useSpring({
        opacity: 1,
        color: 'white',
        from: { opacity: 0 },
        delay: '2000'
    })
    return <animated.div style={props}>This text Faded in Using hooks</animated.div>
}

export default HookedComponent;

We pass the spring settings as an object of arguments to useSpring which will then pass these values to the animated element that then creates our animated spring. We've set our delay to 2000ms to ensure the text from our hooked component fades in after the counter is finished.

Now let's import this into App.js and use the HookedComponent in our app, it should end up looking like this:

//App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Spring  } from 'react-spring';
import Counter from './components/Counter';
import HookedComponent from './components/Hooks';

class App extends Component {
  render() {
    return (

        <Spring from={{ opacity: 0, marginTop: -1000 }} to={{ opacity: 1, marginTop: 0 }}>
          { props => (
            <div  className="App" style={ props }>
              <div >
                <header className="App-header" >
                    <img src={logo} className="App-logo" alt="logo" />
                    <p>
                      Edit <code>src/App.js</code> and save to reload.
                    </p>
                      <a
                        className="App-link"
                        href="https://reactjs.org"
                        target="_blank"
                        rel="noopener noreferrer"
                      >
                      Learn React
                    </a>
                    <Counter />
                    <HookedComponent />
                  </header>
                </div>
              </div>
            )
          }
        </Spring>
    );
  }
}

export default App;

Fire up your final application an see the magic.

Conclusion

You now have the tools to get started using react-spring. While it's the easiest to use component of react-spring, Spring provides a simple yet effective means of animating React applications while taking away a huge amount of the workload from the developer.

Here's the CodeSandbox:

https://codesandbox.io/s/github/austinroy/react-spring-demo

You can build on Spring by making use of react-spring's other components such as Transition which animates component lifecycles and Trail which animates the first element of an array and has the rest follow it in a natural trail. Overall, react-spring is a great package with a variety of options depending on your animation needs.

Nahoru
Tento web používá k poskytování služeb a analýze návštěvnosti soubory cookie. Používáním tohoto webu s tímto souhlasíte. Další informace