DEV Community

The Huferr
The Huferr

Posted on

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;


Enter fullscreen mode Exit fullscreen mode

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;
}


Enter fullscreen mode Exit fullscreen mode

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)


Enter fullscreen mode Exit fullscreen mode

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>


Enter fullscreen mode Exit fullscreen mode

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>


Enter fullscreen mode Exit fullscreen mode

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

Example 1


  <span class="p">&lt;</span><span class="nc">Collapsible</span> <span class="na">label</span><span class="p">=</span><span class="s">'Click Here'</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Profile<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Dashboard<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Logout<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
  <span class="p">&lt;/</span><span class="nc">Collapsible</span><span class="p">&gt;</span>
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode




Example 2



 <span class="p">&lt;</span><span class="nc">Collapsible</span> <span class="na">label</span><span class="p">=</span><span class="s">'Animals'</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Cat<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Dog<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
      <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Cow<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
  <span class="p">&lt;/</span><span class="nc">Collapsible</span><span class="p">&gt;</span>
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode




Results

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:

Github
Linkedin

Top comments (0)