I have created an accordion type ponent 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, acpanied 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
I have created an accordion type ponent 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, acpanied 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
Share Improve this question edited Aug 31, 2021 at 9:04 Inception_K asked Aug 31, 2021 at 8:10 Inception_KInception_K 1451 silver badge9 bronze badges 4-
Each question appears to have its own
isOpen
state, so they should all be independent from one another. I don't see how it's possible for one to toggle all the others. – Drew Reese Commented Aug 31, 2021 at 8:13 - @DrewReese I am trying to open div one when I clicked on toggle first same for others also – Inception_K Commented Aug 31, 2021 at 8:16
-
1
But in my case everytime same div is getting open
, oropen div one when I clicked on toggle first same for others also
. it is not clear what you want to do – Amir-Mousavi Commented Aug 31, 2021 at 8:18 - @Amir-Mousavi I want to if I clicked on first toggle- first div, second toggle- second div, means I want to open different div on different toggle. in my case everytime same div is getting open – Inception_K Commented Aug 31, 2021 at 8:24
2 Answers
Reset to default 3Issue
The issue here is that all Question
ponents have their own state, independent of the others.
Solution
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 ponent. Use an "id" to toggle on/off the question ponent you want to expand. Pass an isOpen
and toggle
props to each Question
ponent 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>
);
};
Update
Ok, since it seems you are struggling with the issue of rendering the same "content" in each Question
ponent 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";
You can do by move isOpen
to the FAQ
ponent and using map
to return questions
in the FAQ:
const [open, setOpen] = useState(null);
const onClick = (i) => {
setOpen(open === i ? null : i);
};
{
questions.map((question, i) => (
<Question key={i} question={question} isOpen={open === i} toggle={() => onClick(i)} />
));
}
in the Question
const Question = ({isOpen, toggle, question}) => {
...
<button onClick={props.toggle}>
{isOpen ? <FaMinus /> : <FaPlus />}
</button>
...
<div onClick={toggle} className="title">
{question}
</div>
...
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745036242a4607535.html
评论列表(0条)