I am new to react so please be kind.
I have an accordion that shows searched terms, I am trying to pass a state down to each child within this accordion but I can’t seem to get the state to toggle when the child is clicked.
So far I have my accordion (I have removed the code around it):
const [isOpen, setIsOpen] = useState(false)
const toggleAccordion = () => {
setIsOpen(!isOpen)
}
return (
<div className='grid'>
{enableSearch && searchComponents}
{accordionData.length > 0
? (
<section className='accordion' data-kontent-item-id={id}>
{title &&
<h2 className='accordion__title'>{title}</h2>}
{accordionData.map(
(item, key) =>
item.title && (
<AccordionItem
key={key}
title={item.title}
text={item.text}
itemId={item.id}
onClick={toggleAccordion}
onKeyDown={handleKeyDown}
isOpen={isOpen}
/>
)
)}
</section>
)
: (
enableSearch && (
<div
className='mt-8'
dangerouslySetInnerHTML={{ __html: noResultsText }}
/>
)
)}
</div>
)
And my accordion item:
const AccordionItem = ({ title, text, itemId, isOpen }) => {
const contentRef = useRef(null)
return (
<div className={`accordion__item ${isOpen ? 'accordion__item-label--expanded' : ''}`} data-kontent-item-id={itemId}>
<div
className='accordion__item-label js-accordion__item-label'
tabIndex={0}
>
</div>
<div
className='accordion__item-content js-accordion__item-content'
ref={contentRef}
>
<div className='accordion__item-content-wrapper' dangerouslySetInnerHTML={{ __html: text }} />
</div>
</div>
)
}
I would like the isOpen state to change when the accordion item is clicked. I am not getting any errors.
2
Answers
You can create a state in the
Accordion
that stores an object lookup that maps the accordion data id to a boolean.Every time you toggle the item, it will invert the inner state.
The following should work:
AccordionItem
should pass theonClick
prop to an actual DOMNode like abutton
element so that when it is clicked it can toggle the state.Example:
The next issue you’ll hit though is that you are using a single
isOpen
state that is passed to all accordion components and they will all be toggled together. My suggestion would be to changeisOpen
from a boolean value to either a nullable string/number type that coincides with the specific accordion you want to have toggled open, or to use an object if you want more than one accordion open at a time.Example:
Single open accordion:
Multiple open accordion: