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 startThis 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
Accordioncomponent 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.

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.

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.

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:
- Build a Custom React Progress Bar Component
- Override a Styled Component in React
- Build a Reusable Icon Component in React
- Add a CSS Class to a React Component

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.