Bringing your components to life

with react-spring

About me

Animating can be hard

React

Defining a component

function Button(props) {
const { text } = props;
return (
<button>
{text}
</button>
);
}

 

Using a component

function App() {
return <Button text="Submit" />;
}

 

Hooks and state

 

useSpring

animates values

useSpring

import React from 'react';
import { animated, useSpring } from 'react-spring';
function Circle() {
const spring = useSpring({
transform: 'translateX(200%)',
});
return <animated.div className="circle" style={ spring } />;
};
export default Circle;

 

Not ideal to animate mounts

useSpring({
transform: 'translateX(-200%)',
})

Reset

useSpring({
reset: true,
transform: 'translateX(200%)',
})

We can reset the animation with the `reset` option

Doesn't seem to work though

useSpring({
reset: false,
transform: 'translateX(200%)',
})

Reset

useSpring({
reset: false,
from: {
transform: 'translateX(-200%)',
},
to: {
transform: 'translateX(200%)',
}
})

To use reset we need a reference point

useSpring({
reset: true,
transform: 'translateX(200%)',
opacity: 1,
})
useSpring({
reset: true,
to: {
transform: 'translateX(200%)',
opacity: 1,
}
})
useSpring({
reset: false,
from: {
transform: 'translateX(-200%)',
},
to: {
transform: 'translateX(200%)',
}
})

Config

useSpring({
config: {
mass: 1,
tension: 170,
friction: 26,
precision: 0.01,
velocity: 0,
clamp: false,
duration: 250,
easing: t => t,
},
...
})

You can configure the physics

Available presets

import { useSpring, config } from 'react-spring';
useSpring({
config:
config.default ||
config.gentle ||
config.wobbly ||
config.stiff ||
config.slow ||
config.molasses,
...
})

Available callbacks

useSpring({
onStart: () => { ... },
onRest: (values) => { ... },
onFrame: (values) => { ... },
})

 

Chaining

const spring = useSpring({
from: {
transform: scale(1)
},
to: [
{
transform: scale(3),
config: config.wobbly
},
{
transform: scale(0),
config: config.gentle
}
]
});

 

Async Chaining

const spring = useSpring({
from: {
transform: scale(1)
},
to: async (next, cancel) => {
await next({
transform: scale(3),
config: config.wobbly
});
next({
transform: scale(0),
config: config.gentle
});
}
});

 

useChain

chain multiple springs together

Specifying delays

useChain(
[ref1, ref2, ref2],
[0, 0.25, 3]
);

 

useTransition

animates entries and exits

Multiple elements transition

const items = [
{ color: 'blue', id: 1 },
{ color: 'purple', id: 2 },
{ color: 'green', id: 3 }
];
const transitions = useTransition(items, (item, index) => item.id, {
config: config.slow,
from: {
transform: 'translateY(-200%)',
opacity: 0,
},
enter: {
transform: 'translateY(0%)',
opacity: 1,
},
leave: {
transform: 'translateY(-200%)',
opacity: 0,
}
});
return transitions.map(transition => {
const { item, key, props } = transition;
return (
<Circle
key={ key }
style={ props }
label={ item.id } />
);
});

 

Unique

const transitions = useTransition(items, keyFn, {
unique: true,
config: config.slow,
from: {
transform: 'translateY(-200%)',
opacity: 0,
},
enter: {
transform: 'translateY(0%)',
opacity: 1,
},
leave: {
transform: 'translateY(-200%)',
opacity: 0,
}
});

 

Functions as steps

const transitions = useTransition(items, keyFn, {
unique: true,
config: config.slow,
from: (item) => ({
transform: 'translateY(-200%)',
opacity: 0,
backgroundColor: item.color
}),
enter: {
transform: 'translateY(0%)',
opacity: 1,
},
leave: {
transform: 'translateY(-200%)',
opacity: 0,
}
});

 

Single element transition

const [show, setShow] = useState(false);
const transition = useTransition(show, null, {
unique: true,
config: config.wobbly,
from: {
transform: 'translateY(-200%) scale(1)',
opacity: 0,
},
enter: {
transform: 'translateY(0%) scale(1)',
opacity: 1,
},
leave: {
transform: 'translateY(0%) scale(0)',
opacity: 0,
},
});
return transition.map(transition => {
const { item, key, props } = transition;
return
item &&
<Circle key={ key } style={ props } />
);

 

Interpolate 🧙‍♂️

Gives you full control over the animated values

That's it! 🎉

Slides are hosted here

react-spring-meetup.netlify.com

Thank you 🙏

Questions?