How to Build an Accordion Component in React

While working on a React project for a client in New York, I needed a simple way to show FAQs without cluttering the page. The best solution? An accordion component.

At first, I thought of using a third-party library, but I realized that building one from scratch would give me more flexibility and control over the styling and behavior. In this tutorial, I’ll show you exactly how I built a React Accordion Component, step by step, using functional components and hooks.

By the end of this tutorial, you’ll be able to create a clean, reusable accordion that fits perfectly into any React app.

What Is an Accordion Component?

An accordion is a UI pattern that allows users to expand and collapse sections of related content. You’ve probably seen it in FAQ pages, pricing sections, or mobile menus.

When a user clicks on a section title, the hidden content expands below it. Clicking again collapses it. This helps keep your interface clean and easy to navigate, especially when you’re working with a lot of content.

Method 1 – Build a Simple Accordion Component in React

Let’s start with the simplest way to create an accordion, using React functional components and the useState hook.

Step 1: Create a New React Project

If you don’t already have a React app set up, open your terminal and run:

npx create-react-app react-accordion-example
cd react-accordion-example
npm start

This will create a basic React project and start the development server.

Step 2: Create the Accordion Component

Inside the src folder, create a new file called Accordion.js and add the following code:

import React, { useState } from "react";
import "./Accordion.css";

const AccordionItem = ({ title, content }) => {
  const [isOpen, setIsOpen] = useState(false);

  const toggleAccordion = () => {
    setIsOpen(!isOpen);
  };

  return (
    <div className="accordion-item">
      <div className="accordion-title" onClick={toggleAccordion}>
        <h3>{title}</h3>
        <span>{isOpen ? "-" : "+"}</span>
      </div>
      {isOpen && <div className="accordion-content">{content}</div>}
    </div>
  );
};

const Accordion = ({ items }) => {
  return (
    <div className="accordion">
      {items.map((item, index) => (
        <AccordionItem key={index} title={item.title} content={item.content} />
      ))}
    </div>
  );
};

export default Accordion;

Here’s what’s happening:

  • Each accordion item has a title and content.
  • We use the useState hook to track whether an item is open or closed.
  • When the title is clicked, we toggle the state to show or hide the content.
  • The Accordion component maps through all items and renders each as an AccordionItem.

Step 3: Add Some Basic Styling

Next, create a file named Accordion.css in the same folder and add this CSS:

.accordion {
  width: 600px;
  margin: 40px auto;
  border: 1px solid #ddd;
  border-radius: 6px;
  background-color: #fff;
}

.accordion-item {
  border-bottom: 1px solid #ddd;
}

.accordion-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  cursor: pointer;
  font-weight: 600;
  background-color: #f9f9f9;
  transition: background-color 0.3s ease;
}

.accordion-title:hover {
  background-color: #f1f1f1;
}

.accordion-content {
  padding: 16px;
  background-color: #fff;
  animation: fadeIn 0.3s ease-in-out;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

This gives your accordion a clean, modern look that fits well into most websites.

Step 4: Use the Accordion Component

Now, open App.js and import your new component:

import React from "react";
import Accordion from "./Accordion";

function App() {
  const faqItems = [
    {
      title: "What is React?",
      content:
        "React is a popular JavaScript library for building user interfaces, maintained by Meta."
    },
    {
      title: "Where can I learn React?",
      content:
        "You can learn React from the official documentation, or through online platforms like freeCodeCamp and Udemy."
    },
    {
      title: "Can I use React for enterprise apps?",
      content:
        "Absolutely! React is widely used across the USA in enterprise-grade applications, from fintech dashboards to healthcare portals."
    }
  ];

  return (
    <div className="App">
      <h2>Frequently Asked Questions</h2>
      <Accordion items={faqItems} />
    </div>
  );
}

export default App;

I executed the above example code and added the screenshot below.

Build an Accordion Component React

Open your browser, and you should see a working accordion. Click on any question to expand or collapse its content.

Method 2 – Accordion with Only One Item Open at a Time

In some cases, you might want only one accordion item open at a time, similar to how FAQs on government or university websites behave.

Here’s how you can modify the code to achieve that.

Replace your previous Accordion.js with this version:

import React, { useState } from "react";
import "./Accordion.css";

const Accordion = ({ items }) => {
  const [activeIndex, setActiveIndex] = useState(null);

  const handleClick = (index) => {
    setActiveIndex(index === activeIndex ? null : index);
  };

  return (
    <div className="accordion">
      {items.map((item, index) => (
        <div className="accordion-item" key={index}>
          <div
            className="accordion-title"
            onClick={() => handleClick(index)}
          >
            <h3>{item.title}</h3>
            <span>{activeIndex === index ? "-" : "+"}</span>
          </div>
          {activeIndex === index && (
            <div className="accordion-content">{item.content}</div>
          )}
        </div>
      ))}
    </div>
  );
};

export default Accordion;

I executed the above example code and added the screenshot below.

Build an Accordion Component in React

This version uses a single activeIndex state to keep track of the open item. If the user clicks on a different item, the previous one closes automatically.

Method 3 – Create a Reusable Accordion with Props and Children

If you’re building a large-scale React app, you might want your accordion to be more flexible, allowing custom content, icons, and animations.

Here’s an advanced example using children’s props:

import React, { useState } from "react";

export const AccordionItem = ({ title, children }) => {
  const [open, setOpen] = useState(false);

  return (
    <div className="accordion-item">
      <div className="accordion-title" onClick={() => setOpen(!open)}>
        <h3>{title}</h3>
        <span>{open ? "▲" : "▼"}</span>
      </div>
      {open && <div className="accordion-content">{children}</div>}
    </div>
  );
};

Usage:

import React from "react";
import { AccordionItem } from "./AccordionItem";

function App() {
  return (
    <div className="App">
      <h2>Company Policies</h2>
      <AccordionItem title="Work From Home Policy">
        <p>Employees in the USA can work remotely up to three days a week.</p>
      </AccordionItem>
      <AccordionItem title="Health Insurance">
        <p>Our company provides full medical coverage through Blue Cross Blue Shield.</p>
      </AccordionItem>
    </div>
  );
}

export default App;

I executed the above example code and added the screenshot below.

React Build an Accordion Component

This approach gives you the flexibility to use any content inside the accordion, text, lists, or even custom components.

Bonus Tip – Add Smooth Transitions

You can make your accordion feel more polished by adding a simple CSS transition:

.accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.accordion-item.open .accordion-content {
  max-height: 200px;
}

Then, toggle the .open class dynamically in React when the item is expanded. This gives a smooth sliding animation effect.

When I first built this component, I realized how much easier it was to customize compared to third-party libraries.
You can easily integrate this accordion into dashboards, help centers, or mobile apps, and style it however you want.

Once you’ve built it, you can even publish it as a reusable component in your internal design system or npm package.

Conclusion

So that’s how I build a React Accordion Component, simple, flexible, and fully reusable. Whether you’re creating a FAQ section for your U.S.-based startup or a policy page for an enterprise app, this component will fit right in.

Both the simple and advanced methods work great. Start with Method 1 if you’re new to React, and move to Method 3 when you need more flexibility.

You may also like to read:

Leave a Comment

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.