This site runs best with JavaScript enabled.

GreenSock Animations with React Hooks


Budding
🌿
Last tended Sep 27, 2020
React
Scrollytelling
Design
JavaScript
Web Development
Greensock

Using the

web animation library (also known as gsap) in vanilla JavaScript isn't too complex. But when we want it to play nicely with a frontend framework like React, we run into some finicky issues.

This guide is specifically about using React Hooks with GreenSock, as many of the

only explain how to set it up with the old style of class components.

This isn't an introduction to the GreenSock library itself – head over to my post on

for that.


React, Meet GreenSock

The issue with combining these two libraries is that React acts as a DOM interloper – it sits between the code we write and the DOM, managing it for us.

React builds it's own internal "tree" of DOM nodes based off our code, and only updates the actual DOM as needed (a concept previously known as the

) The React team has gone off the term of the virtual DOM and prefer to talk about the render tree. Potatoes, potataos. For more on how the virtual DOM works, I have an
illustrated guide

A diagram of React generating all the DOM nodes for us

Meanwhile, the GreenSock library usually works by directly animating our DOM elements. Perhaps you can sense the tension in the room...

Since the GreenSock library needs access to the DOM in order to animate it, we need to tell React about our Greensock animations. Otherwise the two end up in awkward arguments that can end in tears (primarily mine).


Bring in the React Hooks

There's two essential React hooks we'll use to connect our React code to our Greensock code: useRef and useEffect


useRef lets us access and directly target our DOM nodes

useEffect lets us to perform side effects – any functions or data requests that we want to run after rendering the component to the DOM

If you're not completely comfortable with

yet and those technical explanations mean nothing to you, don't worry we're going to slowly walk through this. With illustrations. Because who the fork properly understands "side effects"?


Getting Setup

We first need to run yarn install gsap or npm install gsap into our React project repo gsap is short for GreenSock Animation Platform and it's the way we reference the Greensock library in all our code sytax


Feel free to open up a Codesandbox project to work through the steps while you read. I've set one up for you with React and Greensock already installed:


Building our Animation Component

Let's start by creating a React component called <AnimatedBox/> that is going to hold all our Greensock code. We're going to build a simple <div> element and have it animate across the page (exciting!).

We'll need to import the Greensock library into our component with import { gsap }from 'gsap', as well as React and our two hooks with import React, { useRef, useEffect } from 'react'

1import React, { useRef, useEffect } from 'react'
2import { gsap }from 'gsap'
3
4const Animation = () => {
5 return (
6 <div style={{
7 width: '160px',
8 height: '160px',
9 background: 'salmon'
10 }} />
11 )
12}

I've set some basic width, height, and colour CSS styles on our div to make it visible on the page.

Good looking div, right?
Salmon is always the right colour choice.


Adding the useRef Hook

We're now going to add references to our animation with the useRef hook.

We create a new reference by adding const boxRef = useRef() anywhere outside of our return statement. Call it anything you like, but boxRef is a good enough name for this example.

We then add a ref={boxRef} attribute on our <div> element.

1const Animation = () => {
2 const boxRef = useRef()
3
4 return (
5 <div ref={boxRef} style={{
6 width: '160px',
7 height: '160px',
8 background: 'salmon'
9 }} />
10 )
11}

This tells React we want to be able to control our <div> element with the boxRef reference once our component is mounted onto the DOM.


Adding the useEffect Hook

Next we're going to add our useEffect hook, and write our GreenSock animation inside of it.

If you're already familiar with greensock this will look fairly straightforward.

1const Animation = () => {
2 const boxRef = useRef()
3
4 useEffect(() => {
5 gsap.to([boxRef.current], {
6 x: '400px',
7 duration: 2
8 })
9 })
10
11 return (
12 <div ref={boxRef} style={{
13 width: '160px',
14 height: '160px',
15 background: 'salmon'
16 }} />
17 )
18}

We declare a normal gsap.to() tween, but instead of passing in an id or class name as the target element, we use [boxRef.current].

This means we want gsap to animate the .current property of our boxRef reference – which is the <div> element we put that reference on.

1gsap.to([boxRef.current], {
2
3})

We then pass in our variables object, which tells Greensock to move our div 400px along the x axis over a duration of 2 seconds:

1{ x: 400px, duration: 2 }

And thus, our div animates...

Tada 🎉

So by this point, you hopefully have a working animation in that

or a local repo.


If you don't feel like mucking around with useRef and useEffect,

created a simple React hook called use-gsap that hides them away.

Want to share?

Join the newsletter

For weekly notes on visual thinking, ethical technology, and cultural anthropology.

Maggie Appleton © 2022