I'm SPRUNG! A react-spring series // Part 1: Intro & the useSpring hook 🦘
Tags: react, tutorial, javascript, webdev
Published: 2022-12-11 11:07:32

# I'm SPRUNG!

Yes this series is named after the 2005 song by T-Pain... 

## What is React Spring?

React Spring is a **spring-physics** based animation library. Instead of manipulating time, we give our elements mass, tension, and friction to mimic how things move from one position to another in real life. 

## Ok then... so how do we actually animate things?

First we have to get a few things out of the way.
 
## 1. The `animated` component

We can only animate `animated` components, these are provided by the `react-spring` library. We can also use `a` to denote an animated component as well

```
import { animated, a } from '@react-spring/web'

<animated.div /> // will animate

<span /> // won't animated

<a.h2 /> // will animate
```

## 2. We define our springs in **two** ways:

- As an config object
- Or as an anonymous function passed into the hook

```
// This spring will run when the component mounts 

const spring = useSpring({
    from: {opacity: 0, 'translateY(100%)'},
    to: {opacity: 1, 'translateY(0)'}
})

// This spring will run based on state

const [active, setActive] = useState(false)

const spring = useSpring({
    opacity: active ? 1 : 0,
    transform: active ? 'translateY(0%)' : 'translateY(100%)'
})

/*
   And lastly we can use an imperative method. We use array 
   destructuring to receive a controller object. We just need 
   to pass an anonymous function with our config object.
   This method doesn't rely on the components lifecycle. 
*/ 

  const [styles, api] = useSpring(() => ({
    opacity: 0,
    transform: 'translateY(100%)'
  }));

  api.start(({
    opacity: 1,
    transform: 'translateY(0%)'
  }))

```

## Our first animation

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1vc5z491kimgcgbgzitj.gif)

```
const [active, setActive] = useState(false)

const spring = useSpring({
   opacity: active ? 1 : 0,
   transform: active ? 'translateY(0%)' : 'translateY(100%)' 
})

const handleClick = () => {
   setActive(state => !state)
}

return (
    <a.p style={spring}>Poof!<a.p>
    <button onClick={handleClick}>Click Me!</button>
)
```

Above we see that the spring will only trigger based on the state of `active`. By default it will be invisible, and its starting position will be 100% of its origin on the Y axis (this means it will animate bottom - up). We've also passed the whole spring. But we can also use the spread operator...

```
return (
    <a.p {...spring}>Poof!<a.p>
    <button onClick={handleClick}>Click Me!</button>
)
```

## Our second animation

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/namestj47icqd4f83jut.gif)

But what if we want to apply this spring to multiple elements   in an array? React-spring has a dedicated hook for that `useSprings`, which we'll cover in the next post, but we can actually use the `useSpring` hook to do this, although it will be limited. All we have to do is map over the array and apply it to each rendered jsx element

```
/*
  Lets say we have four boxes we want to spin and turn into 
  circles
*/
const Example = () => {
   const [active, setActive] = useState(false)
   const elements = ['Item 1', 'Item 2', 'Item 3', 'Item 4']

   const animation2 = useSpring({
       transform: isActive ? 'rotate(720deg)' : 'rotate(0deg)',
       borderRadius: isActive ? '50% 50%' : '0% 0%',
       backgroundColor: isActive ? '#FF7518' : 'rgb(255, 255, 255)',
       color: isActive ? 'rgb(255, 255, 255)' : 'rgb(0, 0, 0)',
       transformOrigin: 'center',
   });

   const handleClick = () => {
      setActive(state => !state)
   }

   return (
      {elements.map(el => <a.p style={spring}>{el}<a.p>)}
      <button onClick={handleClick}>Click Me!</button>
   )
}
```
This is nice if you simply want all the elements to have the same animation all happening at once.

## Conclusion

**Things to note about the `useSpring` hook:** 

- Components will reverse their animation when tied to a state variable. If using the imperative method, springs will jump from the end state to the beginning position and run again

- Remember that your components, even if their opacity is set to 0, they are still mounted on the DOM. They're **never unmounted**. We will take a look at mounting and un-mounting elements using the `useTransition` hook in the future 

This wraps up the first part of the react-spring series! So stay tuned for part 2 on the `useSprings` hook!