Driving react-spring animations behaviour through strategies

Sebastian Gonzalez
Nov 30, 2020 · 4 min read

Dealing with animations can make a simple component become complex that it loses its main qualities: atomicity, reusability, testability, composability to name a few.

Libraries like react-spring came to make animations a more pleasant and fun task to do. However, it does not prevent the code from becoming more complex, difficult to read and test.

One of the last experiences that forced me to think about how to separate animation behavior from presentational logic was the SteppedSlider component whose purpose is to display any set of elements that are provided as children, also giving them the ability to slide them as a carousel. To make the task even more complex, the SteppedSlider component can align its children in different ways, varying the behavior of the animation depending on the case.

To achieve this purpose, I gave the SteppedSlider component the ability to choose its animation strategy based on one of its props.

This is the result, you can play with it on CodeSandbox, or check the repo.

justify align strategy
justify align strategy
Justify align strategy
center align strategy
center align strategy
Center align strategy

Let’s see how it works!

The first thing we can see is the following interface

A component whose children can be any node that React is capable of rendering. In this case, an array of <img /> nodes.

Let’s see then what happens inside the SteppedSlider component, which has the responsibility of distributing, aligning, and animating its children.

We can divide it into 3 steps

  1. Render all children regardless of their type.
  2. Give them interactivity (react-use-gesture — useDrag).
  3. Animate the interactions (react-spring — useSprings) applying the corresponding strategy.

The important thing is that none of the children (imgs)is coupled to the behavior granted by the animation strategy.
Whatever the type of children, SteppedSlider doesn’t care.

Let’s analyze each part

1. Render all children regardless of their type.

The render is as simple as that. Just map the springs (one for each slide) and place each one in an ImageContainerDiv (Styled Div) passing it some props that we will see next.

If you are not familiar with how react-spring or react-use-gesture work, I recommend that you look at the documentation to get an idea. Otherwise, this part could be hard to follow.

2. Give them interactivity (react-use-gesture — useDrag).

This section is in charge of capturing the gestures that a user performs on the slides. Decide when to follow the user’s movement and when to make the slide change using the following line

setSprings(calculateMovement({ someValues }))

3. Animate the interactions (react-spring — useSprings) applying the corresponding strategy.

The beautiful and inevitable math of animation aside, the code is very simple. The function called calculateMovement will be called every time the user interacts with our components and will be in charge of determining the new position / style of our slides on the screen.

Full SteppedSlider component code:

As I mentioned before, the behavior of the animation is not the same in all cases, but depends, for example, on the type of alignment that we have given it. That is why I have defined the AlignStrategies module.

The SteppedSlider component now has the ability to vary the behavior of the animation based on the value of its align property.

In the following line,
AlignStrategies[align]({ x, offsetPercentage, spacingPercentage, currentSlideIndex, slidesCount });
the respective strategy is executed and the behavior is changed.

The alignment strategies are nothing more than simple functions that fulfill the same interface and in this case they define how much the slides should move. But it could be anything the use case indicates

Now the SteppedSlider component has infinite alternatives to vary its behavior without increasing its complexity or reducing its readability.

Beyond the particular case that I bring you, this approach has many advantages when developing web components.

For example, strategies could be defined to vary the behavior of the animations according to the size of the device, the processing capacities, or even the type of user, showing simpler animations to new users and more complex ones to more experienced users.

We were able to extract the most complex part of the animation logic to an external module, even giving it the ability to be reusable and testable without losing the composability and single-responsibility of our main component.

Just as we extracted the alignment, we could extract any other portion of logic, for example, the one referring to the scaling of the slides. Although in this case, it did not seem necessary.

Thank you for letting me share my experience with you, I hope you can take advantage of it.

See you!

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Sign up for 💌 Weekly Newsletter

By Weekly Webtips

Get the latest news on the world of web technologies with a series of tutorial Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Sebastian Gonzalez

Written by

I'm a software developer, passionate about learning and traveling

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Sebastian Gonzalez

Written by

I'm a software developer, passionate about learning and traveling

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store