CLEVER°FRANKE
Published in

CLEVER°FRANKE

Create a React SlideToggle component with hooks and react-spring

Everybody who has been writing Javascript for more than a few years must have come across jQuery’s and methods. You can say about jQuery what you want, but these methods were very easy and helpful. When I first started using a component based framework such as React I really missed an easy way to mount and unmount content with a fancy transition. For quite some time I have been dependent on the component from React Transition Group. It gets the job done, but in an era of Hooks and spring physics it’s renderProp API feels a bit outdated and the animations a bit sluggish.

Because we at CLEVER°FRANKE have been a heavy users of Hooks since React came out and since React Spring now added a very easy Hooks interface in , I decided to combine the best of both worlds to create a reusable SlideToggle component. Below I will describe my process and choices so it may hopefully help you or others.

The Process

The first thing we need to do is make sure we are running a React version that supports hooks and install react-spring via:

npm install --save react-spring

and create a component that will serve as the wrapper element.

SlideToggleContent component

The component will have three props:

  • which will make sure the children will be mounted and slided down.
  • will be an optional prop that makes sure the component slides down on it’s initial render.
  • will contain the children elements.

Next we will need to add the actual HTML elements and add references to them so that React can interact with them. The new Hooks API provides the hook that “returns a mutable ref object whose property is initialized to the passed argument (). The returned object will persist for the full lifetime of the component” (See the React docs).

We need a little bit of styling to prevent margins of the children elements from overflowing the container. I’m using Styled Components but you can of course choose any other styling method.

Add HTML elements with proper references

Now it is time for the React Spring magic to come into play. We will be using the hook since we are mounting and unmounting the children elements and this hook provides , and properties just like the Transition component from React Transition Group. These properties allow you to add basic styling objects or more advanced functions that can chain multiple style changes. The latter is very useful in our case because we want to calculate the proper final element height and make sure that after that the css property is set to . Furthermore we want to control the property and set it to whenever the animation changes.

The hook can mount multiple instances of at once, for example when the component is toggled before the animation is ended. This is something we want to prevent because we don’t want duplicates of our content showing up. React Spring provides the property which will make sure items with the same key will be reused and never rendered more than once. In our case we can omit the parameter and set it to because we will only animate one single element. React Spring will make sure the elements receives a proper key.

will return an Array of transitionable element objects each containing an , and that contain respectively a reference to the actual element, the styling properties and the unique key. The styling properties can be applied on an component provided by React Spring which will make sure the styling props are transformed into actual animations.

Animate height via useTransition

Almost there! We now have a working SlideToggle component. It is however missing one important feature. At this point the component will always start from also when was on the components initial render. So we need to make sure that the property changes based on the initial value of . In order to remember that initial value we can use the hook again because as said above that will persist the value throughout the lifetime of the component.

const isVisibleOnMount = useRef(isVisible && !forceSlideIn);

And change the property to:

from: isVisibleOnMount.current ? visibleStyle : hiddenStyle

Demo

You can find a working demo of this component here. Feel free to reuse it!

Disclaimer

With a little bit of code we’ve been able to create a reusable and easily customisable SlideToggle component. Adding React Spring to your bundle for only this use case may be a bit overkill but I can assure you that once it’s added to your bundle and you start playing with it, you will certainly find more UI elements that can be brought to life with spring animations!

--

--

Sharing our thoughts on data driven experiences and data visualization

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