I implement the accordion but now I want to show only one particular item at a time. I know there are plenty answers available in this platform regarding this same problem but I can't find any suitable solution. Actually, I don't want to add any class in the active item and don't want to do that with CSS. With pure JavaScript, how can I achieve this? Here is my code:
const PerFAQ = ({ ques, ans }) => {
const [isShown, setIsShown] = useState(false)
return (
<>
<li>
<a onClick={() => setIsShown(!isShown)}>{ques}
{
!isShown ? <BsChevronDown /> : <BsChevronUp />
}
</a>
{
isShown && <ul>
<li>
{ans}
</li>
</ul>
}
</li>
</>
)
}
Willing to share more code if needed.
CodePudding user response:
You can do this by lifting the isShown state up.
For example:
const ListItem = ({visible, onExpand}) => {
return(
<div>
<button onClick={onExpand}>Expand</button>
{visible && <p>your content</p>}
</div>
);
}
const List = ({items}) => {
const [visibleIdx, setVisibleIdx] = useState(-1);
return (
<div>
<ListItem visible={visibleIdx == 0} onExpand={() => setVisibleIdx(0)} />
<ListItem visible={visibleIdx == 1} onExpand={() => setVisibleIdx(1)} />
</div>
)
}
Edit: It might be unclear what I meant. The React components form a tree hierarchy. Each item has children. The state of a component is stored by the component itself. You can pass these components down to its children, but cannot pass it up, to its parents. If you need to access the state from the parent, the only solution is to lift it up. That means you need to move the state to the parent component, and that component needs to pass it down to its children.