Reusable Collapsible Component with ReactJS

Welcome, here's a guide teaching you how to create a simple and useful Reusable Collapsible Component, with ReactJS.

Observation: I created this post considering that you know the basics of ReactJS. If you see anything wrong, please tell me!

You can see it working at CodePen: https://codepen.io/huferr/pen/NWjNLMy

Let's start by creating a functional component and call it Collapsible. It will return some HTML elements, which will structure our layout.

For this case, let's set:

  • A div element, which will keep all the elements bellow;
  • A button element, responsible for toggling the content visibility;
  • A div element, which will handle our content.

Now, to make this component reusable, we have to pass some properties to it, to make this component accept data from outside, not having to change its structure every time.

For this we'll set the props: children and label, by doing props destructuring, it means you don't have to call "props.children" or "props.label" every time you want to use these props. You only have to pass the prop names inside a curly brackets in the function.

Let's see what we've done so far:

import React from "react";
import "./styles.css";

const Collapsible = ({ children, label }) => {
  return (
    <div className="container">
      <button className='toggle'>{label}</button>

      <div>{children}</div>
    </div>
  );
};

export default Collapsible;

OK, we have our button, that will make the content appear and disappear and we have our div with that content.

First thing, to make the content toggle, we'll need to set a CSS class (.show) to style how it's going to appear on our screen, and an other class (.content) to make it disappear:

.content {
    width: auto;
    height: auto;
    margin-top: 10px;
    border: 1px solid #686868;
    display: none;
    justify-content: center;
    border-radius: 10px;
}

.show {
    display: flex;
}

As you can see, the magic is on the display property. When the div has the .show class, the content will be displayed!

Now, to make the toggle effect when click on the button, let's use the useState Hook! With this, let's set isOpen and setIsOpen, initializing with false.

Obs.: Do it in the same Collapsible component.

import React, {useState} from 'react'
import './styles.css'

const Collapsible = ({children, label}) => {

    const [isOpen, setIsOpen] = useState(false)

Good! Now, with the onClick event in the button, let's pass a simple arrow function, setting the isOpen true or false, according to its previous state (if isOpen === false, set to true and vice-versa), using !, the logical "not" operator in javascript. See it:

<button className='toggle' onClick={() => setIsOpen(!isOpen)}>{label}</button>

After that, to bind this event with the content, let's use a ternary operator in the content div class. So, isOpen === true ? use 'content and show' classes (content appears), isOpen === false ? use only 'content' (content disappears). See it:

<div className={isOpen ? 'content show' : 'content'}>{children}</div>

Now, we have a Reusable Collapsible Component! You can change the label and children (content) prop, where the component will stay:

Example 1

<Collapsible label='Click Here'>
        <ul>
          <li>Profile</li>
          <li>Dashboard</li>
          <li>Logout</li>
        </ul>
      </Collapsible>

Example 2

<Collapsible label='Animals'>
        <ul>
          <li>Cat</li>
          <li>Dog</li>
          <li>Cow</li>
        </ul>
      </Collapsible>

Results

OTHER OBSERVATION: The purpose of this post was to show the functionality, so, sorry for the bad styling haha!

Done! Thanks for reading this content, I hope it helps you in some way and, if you notice something wrong, feel free to help me leaving a comment bellow or find me on twitter !

You can also find me at:

23