Skip to main content

Controlling state

From above Accordion

If you want to programmatically open or close accordion items from a component that is above Accordion in the React tree, you could use the ControlledAccordion and useAccordionProvider.

The value returned from useAccordionProvider contains a toggle function which can be used to open or close any accordion items. This value should also be given to the providerValue prop of the ControlledAccordion component.

The toggle function accepts two parameters. The first parameter is the itemKey prop of any accordion items to toggle. The second parameter specifies whether to open or close an item using a boolean value, or to toggle between the two states if the parameter is omitted.

import {
ControlledAccordion,
AccordionItem,
useAccordionProvider
} from '@szhsin/react-accordion';

export default function Example() {
const providerValue = useAccordionProvider({
allowMultiple: true,
transition: true,
transitionTimeout: 250
});
// Destructuring `toggle` and `toggleAll` from `providerValue`
const { toggle, toggleAll } = providerValue;

return (
<div>
<div className="buttons">
<button
className="btn"
// Toggle between open and close by omitting the second parameter
onClick={() => toggle('item-1')}
>
Toogle the first item
</button>
<button
className="btn"
// Open rather than toggling
onClick={() => toggle('item-3', true)}
>
Open the last item
</button>
<button
className="btn"
onClick={() => toggleAll(true)}
>
Open all items
</button>
<button
className="btn"
onClick={() => toggleAll(false)}
>
Close all items
</button>
<button
className="btn"
// Omitting the boolean parameter means toggling
onClick={() => toggleAll()}
>
Toggle all items
</button>
</div>

<ControlledAccordion
// Forward the `providerValue` directly to `ControlledAccordion`
providerValue={providerValue}
>
<AccordionItem
header="What is Lorem Ipsum?"
// Set an explicit `itemKey`
itemKey="item-1"
>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
</p>
<button
className="btn"
// It also works within the `AccordionItem` children
onClick={() => toggle('item-3')}
>
Toggle the last item
</button>
</AccordionItem>

<AccordionItem header="Where does it come from?">
Quisque eget luctus mi, vehicula mollis lorem. Proin fringilla
vel erat quis sodales. Nam ex enim, eleifend venenatis lectus
vitae, accumsan auctor mi.
</AccordionItem>

<AccordionItem
header="Why do we use it?"
// Set an explicit `itemKey`
itemKey="item-3"
>
Suspendisse massa risus, pretium id interdum in, dictum sit
amet ante. Fusce vulputate purus sed tempus feugiat.
</AccordionItem>
</ControlledAccordion>
</div>
);
}
NOTE

The itemKey prop of AccordionItem is not required to be globally unique, but it should be unique among its sibling AccordionItem components.

Also, you don't need to specify the itemKey prop for an item if you don't want to programmatically toggle it.

From underneath Accordion

To programmatically open or close accordion items or access the state from a component that is underneath Accordion in the React tree, use the useAccordionState hook.

Next item expanded: false

import {
Accordion,
AccordionItem,
useAccordionState
} from '@szhsin/react-accordion';

const MyItem = () => {
const { getItemState, toggle, toggleAll } = useAccordionState();

return (
<AccordionItem header="My custom accordion item" initialEntered>
<p>
{/* Accessing item state by providing an `itemKey` */}
Next item expanded: {getItemState('next').isEnter.toString()}
</p>

<div className="buttons">
<button className="btn" onClick={() => toggle('next')}>
Toggle next item
</button>

<button className="btn" onClick={() => toggleAll(false)}>
Close all items
</button>
</div>
</AccordionItem>
);
};

export default function Example() {
return (
<Accordion allowMultiple>
<MyItem />

<AccordionItem
header="What is Lorem Ipsum?"
itemKey="next"
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</AccordionItem>
</Accordion>
);
}
tip

If you want to access and control state of the current item, there is a simpler way to achieve it using the render prop pattern.