In this tutorial you will learn how to create an animated React accordion component using React Hooks like
In simplest form, React Hooks make it possible to use state without the need to create a class. If that’s enough to sell you on using Hooks, then read (or watch) on. However, if you’d like a deeper dive into React Hooks check out Making Sense of React Hooks by Dan Abramov, co-author of Redux and Create React App.
You can get the final code here from CodeSandbox.io. I’ve also recorded the entire process in the video below and outlined each step in the subsequent post–enjoy!
To get started head to CodeSandbox.io and sign up with your GitHub account. CodeSandbox is a web-based code editor that makes it easy to write code and create web applications without the need to setup anything locally on your computer–perfect for a quick tutorial.
Once you’re on the dashboard click on the Create Sandbox button and select the React Client Template. This will create a basic React application that you can start using to build the accordion.
Before you start writing the accordion component the first thing you want to do is remove the out-of-the-box styling in the
styles.css file. Then add the following global styles:
box-sizing: border-box ensures that padding is added to the inside of elements while
margin: 0 and
padding: 0 ensures the browser isn’t adding any default padding to elements.
After cleaning up some of the boilerplate code go ahead and create a new folder in your project called
Components. Inside this folder create two files:
Accordion.css. You’ll start with the most basic version of the accordion component, only passing in props and not using React Hooks. You’ll add React Hooks later in the tutorial. With that said, open the
Accordion.js file and add the following:
In this code you created a simple function (stateless) component, passing in props. One prop you used is
dangerouslySetInnerHTML. It’s important to note that improper use of
dangerouslySetInnerHTML can open you up to a cross-site scripting (XSS) attack. Before using dangerouslySetInnerHTML in your project be sure to read How to prevent XSS attacks when using dangerouslySetInnerHTML in React by Jacob Jang.
With the most basic form of the accordion component built you can now import it into your
index.js file and use it in the return, passing in props for
content like so:
For the demo I used LoremIpsum.io to generate filler text. It’s also important to note that in the last accordion I wrote HTML within the content prop in order to show you how
dangerouslySetInnerHTML will render HTML within a string.
Now it’s time to style the accordion component by writing the following in the
I’ll spare too much detail here and refer to the comments I left in the CSS file to explain what the classes are doing. However, I do think it’s important to point out that you’ll be passing in some styles like
.rotate to React state later in the tutorial. Also, the
transition property is being used on classes like
accordion__icon to create smooth animated transitions when a CSS property changes or when new classes are added to elements.
Each accordion will have a chevron on the right side that will rotate to point downwards when active. To create the chevron you’ll start by going to FontAwesome.com and downloading the SVG for the chevron-right icon. Here’s a quick GIF on how to do that:
Once the SVG finishes downloading open it in a text/code editor of choice. Then copy everything in the file and head back to CodeSandbox. Once you’re there create a new file in the
Components folder called
Chevron.js and write a simple function component, passing in what you copied from the SVG in the return like so:
Notice the props this component is using:
fill. You’ll use those in the
Accordion.js file like so:
Now let’s get to the real reason you’re here: React Hooks!
The first hook you’ll use is
useState(), which you’ll add to your Accordion component. With hooks there’s no need to convert a function component into a class component–just initialize the hook like so:
First, you’ll need to import
useState from React. Then you’ll use array destructuring syntax to set the current state value (
setActive) and function that allows you to update the state (
setActiveState). This new constant is set equal to
useState and the only argument
useState needs is the initial value, which in this case is an empty string.
Now that you have your first state defined you need to create a function within the component that will be called when the accordion is clicked by an user. To make sure it’s clear what the function does, you can name it
This first thing this function will do is call
setActiveState() you’ll write the following ternary operator:
setActiveState(setActive === “” ? “active" : “”. This ternary operator is checking if
setActive is empty, and if it is it will change the state to active. If it is already set to
active it will set it to an empty string.
You can then use the value of
setActive within the button
className using a template string. Last, pass an
onClick event listener that calls the new
Now when you save your project you can click on the accordion and the background color will stay the value you set on the
.active class in your
Accordion.css file. You can always inspect the element to see the class toggle from
The next React Hook you’ll use in the tutorial is
useRef(). This hook will create a reference to a DOM element, which you can then get data off of by accessing
.current. The data you want to access is
scrollHeight, which gives you the height of an element even when the element’s overflow is hidden.
You then can use the data from
scrollHeight to change the max-height of the content within the accordion, which you’ll initially set to 0. Doing this will create an animated expand/collapse effect for the accordion content.
To start you need to import
useRef from React and initialize it within the accordion component. You can call this reference
content so it’s easy to remember what it’s referencing. You’ll also want to set its initial value to
Then you can set the reference on the content element by passing in the following HTML attribute:
In order to see the value of each reference you can
console.log the value in the
toggleAccordion function. By now you should have the following code:
Now you can open the console within CodeSandbox and see the
scrollHeight of each accordion content section printing to the console when you click on it. Feel free to remove the
console.log once you’re done testing it out.
With access to the accordion’s content height you can now use that value to create the animated expand/collapse effect. To start you’ll need to create a new state called
useState–just like you did for
This time set the initial state to
0px because you’ll be using that value to make sure all the content is hidden when the accordion components are rendered.
You’ll also change
setHeightState, which you’ll call in the
toggleAccordion function. Just like with
setActiveState you will write a ternary operator, but this time you’re checking if
setActive is equal to
active. If it is the function will change
0px. Else, if it’s already
0px it will change to the value of the accordion’s content
Finally, you’ll use the value of
setHeight to set the
maxHeight via an inline style. With that your code should appear as follows:
Once you save that you can click on each accordion to reveal the content. Feel free to change the speed and acceleration of the animation in the
transition property of the
.accordion__content class in your
You’re at the homestretch! The last thing you want to do is animate the chevron to point downwards by rotating it 90 degrees clockwise when the accordion’s
setActive state is active.
To do this you’ll create a new state called
setRotate. You’ll set the initial value equal to the string
accordion__icon and write a similar ternary operator in the
toggleAccordion function that checks the current value of
setActive. This time if
setActive is equal to
active the function will change the
setRotate value to
accordion__icon. Else, if it’s not active it will change
accordion__icon rotate. You’ll then use the value of
setRotate to dynamically change the
className of the chevron. Your
Accordion.js component should look like this:
And that’s it! Now when you click on an accordion the chevron will rotate downwards. Click again and the accordion will revert to its initial state.
.accordion__content, you can tweak the animation by changing the
transition property on the
.accordion__icon class in your
I hope this tutorial was a great example of how to use React Hooks. If you enjoyed the tutorial be sure to check out my other courses on the Skillthrive YouTube channel. And as always, if you have any questions feel free to drop them below.