Reputation: 33
when I click on the button all accordion elements are opened. how to make only clicked element to be opened. this is a react accordion app. I am not able to find the problem in the code.
import React, { useState } from "react";
//import {questions} from './api';
const questions = [
{
id: 1,
question: "what is a",
answer: "a is a"
},
{
id: 2,
question: "what is b",
answer: "b is b"
},
{
id: 3,
question: "what is c",
answer: "c is c"
}
];
function Accordian() {
const [toggle, settoggle] = useState(false);
function mapfunc(currentValue) {
return (
<div key={currentValue.id} className="elements">
<h3 className="question">
{currentValue.question}
<button
onClick={function () {
settoggle(!toggle);
}}
className="button"
>
{toggle ? "➖" : "➕"}
</button>
</h3>
{toggle && <p className="answer"> {currentValue.answer} </p>}
</div>
);
}
return (
<div>
<h1>Accordian App</h1>
{questions.map(mapfunc)}
</div>
);
}
export default Accordian;
Upvotes: 0
Views: 408
Reputation: 1651
The problem here, is that the state is at the Accordion level. So if it is true, all of the children of the Accordion will be opened.
Instead, you should create a children component, that take as argument a question, and that has a local toggle
state.
You could instantiate it like this for instance:
return (
<div>
<h1>Accordian App</h1>
{questions.map(question => <AccordionChildren question={question} />)}
</div>
)
Upvotes: 0
Reputation: 13265
You need to move the toggle item with its logic to a separate component.
import React, { useState } from "react";
const Item = ({ currentValue }) => {
const [toggle, settoggle] = useState(false);
return (
<div key={currentValue.id} className="elements">
<h3 className="question">
{currentValue.question}
<button
onClick={function () {
settoggle(!toggle);
}}
className="button"
>
{toggle ? "➖" : "➕"}
</button>
</h3>
{toggle && <p className="answer"> {currentValue.answer} </p>}
</div>
);
};
const questions = [
{
id: 1,
question: "what is a",
answer: "a is a"
},
{
id: 2,
question: "what is b",
answer: "b is b"
},
{
id: 3,
question: "what is c",
answer: "c is c"
}
];
function Accordian() {
return (
<div>
<h1>Accordian App</h1>
{questions.map((item) => (
<Item currentValue={item} />
))}
</div>
);
}
export default Accordian;
Upvotes: 2