I have created an accordion type component in reactjs In this When I open the first toggle, only toggle one content should open, when clicked on second toggle then the toggle one content should close and only toggle second content should be open(Only one toggle should be open at a time) . But in my case everytime same div is getting open. I don't know where I did wrong? and how to solve it?. below is my code
import React, { useState } from "react";
import { FaPlus, FaMinus } from "react-icons/fa";
import "./FAQ.scss";
import { Collapse } from "reactstrap";
const Question = (props) => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
return (
<div className="question">
<div>
<button onClick={toggle}>
{isOpen ? <FaMinus /> : <FaPlus />}
</button>
</div>
<div onClick={toggle} className='title'>
{props.question}
</div>
<Collapse isOpen={isOpen} className='content'>
The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for
those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum"
by Cicero are also reproduced in their exact original form, accompanied by English
versions from the 1914 translation by H. Rackham.
</Collapse>
<hr />
</div>
);
};
function FAQ() {
return (
<div className="faq" id='faq'>
<h2>F.A.Q.</h2>
<div className="faq-section">
<Question question="Question one" />
<Question question="Question two" />
<Question question="Question three" />
<Question question="Question four" />
<Question question="Question five" />
</div>
</div>
);
}
export default FAQ;
The screenshot is given in the below 
UPDATE THE QUESTION
Below is the link of a website the have the FAQ section in the bottom, I am trying to make the toggle feature as they have. FAQ section in the bottom of this website
The issue here is that all Question components have their own state, independent of the others.
If you want to only open one Question at-a-time then the state needs to be lifted and declared in FAQ. This is so there's a single source of truth for what is opened/expanded.
FAQ
Move the isOpen state and toggle handler to this parent component. Use an "id" to toggle on/off the question component you want to expand. Pass an isOpen and toggle props to each Question component and handle the id logic here.
function FAQ() {
const [isOpen, setIsOpen] = useState(null);
const toggleOpen = id => () => setIsOpen(
isOpen => isOpen === id ? null : id,
);
return (
<div className="faq" id='faq'>
<h2>F.A.Q.</h2>
<div className="faq-section">
<Question
question="Question one"
isOpen={isOpen === 0}
toggle={toggleOpen(0)}
/>
<Question
question="Question two"
isOpen={isOpen === 1}
toggle={toggleOpen(1)}
/>
<Question
question="Question three"
isOpen={isOpen === 2}
toggle={toggleOpen(2)}
/>
<Question
question="Question four"
isOpen={isOpen === 3}
toggle={toggleOpen(3)}
/>
<Question
question="Question five"
isOpen={isOpen === 4}
toggle={toggleOpen(4)}
/>
</div>
</div>
);
}
Question
Call/consume the isOpen and toggle from the passed props.
const Question = (props) => {
return (
<div className="question">
<div>
<button onClick={props.toggle}>
{props.isOpen ? <FaMinus /> : <FaPlus />}
</button>
</div>
<div onClick={props.toggle} className='title'>
{props.question}
</div>
<Collapse isOpen={props.isOpen} className='content'>
....
</Collapse>
<hr />
</div>
);
};
Ok, since it seems you are struggling with the issue of rendering the same "content" in each Question component I suggest you load up all your questions and content into an array and map them instead of hardcoding the JSX.
FAQ
const faqData = [
{
question: "Question one",
content: <div> .... I'm content .... </div>, // <-- anything renderable as a child
},
... etc...
];
function FAQ() {
const [isOpen, setIsOpen] = useState(null);
const toggleOpen = id => () => setIsOpen(
isOpen => isOpen === id ? null : id,
);
return (
<div className="faq" id='faq'>
<h2>F.A.Q.</h2>
<div className="faq-section">
{faqData.map(({ content, question}, index) => (
<Question
key={index}
content={content}
question={question}
isOpen={isOpen === index}
toggle={toggleOpen(index)}
/>
))}
</div>
</div>
);
}
Question
const Question = ({ content, question, isOpen, toggle }) => {
return (
<div className="question">
<div>
<button onClick={toggle}>
{isOpen ? <FaMinus /> : <FaPlus />}
</button>
</div>
<div onClick={toggle} className='title'>
{question}
</div>
<Collapse isOpen={isOpen} className='content'>
{content}
</Collapse>
<hr />
</div>
);
};
And just in case you missed it, you also need to import the bootstrap CSS somewhere in your project to get the bootstrap styles, transitions, and animations working.
import "bootstrap/dist/css/bootstrap.min.css";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With