Search code examples
javascriptreactjsnext.jsreact-bootstrap

Attempt to persist React-Bootstrap Accordion state on localStorage not working


My project is on Next.js. So, I am trying to save the last Accordion state to localStorage, so that when I reload the page, the previous loaded Accordion will again stay open. But even though I am passing the correct array of keys inside the defaultActiveKey option, it's not working.

Here is my code so far.

import { useState, useEffect } from 'react'
import Accordion from 'react-bootstrap/Accordion'

export default function Example() {
    let [expandedItem, setExpandedItem] = useState(new Array())

    useEffect(() => {
        setExpandedItem(JSON.parse(localStorage.getItem('expandedItem')));
    }, [])

    return (
        <Accordion
            alwaysOpen
            defaultActiveKey={expandedItem}
            onSelect={e => {
                if (e !== null) {
                    setExpandedItem(e);
                    localStorage.setItem('expandedItem', JSON.stringify(e));
                }
            }}>
            <Accordion.Item eventKey="0">
                <Accordion.Header>Accordion Item #1</Accordion.Header>
                <Accordion.Body>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
                    eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
                    minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                    aliquip ex ea commodo consequat. Duis aute irure dolor in
                    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
                    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
                    culpa qui officia deserunt mollit anim id est laborum.
                </Accordion.Body>
            </Accordion.Item>
            <Accordion.Item eventKey="1">
                <Accordion.Header>Accordion Item #2</Accordion.Header>
                <Accordion.Body>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
                    eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
                    minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                    aliquip ex ea commodo consequat. Duis aute irure dolor in
                    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
                    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
                    culpa qui officia deserunt mollit anim id est laborum.
                </Accordion.Body>
            </Accordion.Item>
        </Accordion>
    );
}

Solution

  • Since you're setting the key on mount after the component has hydrated, you should use the activeKey prop instead of defaultActiveKey.

    <Accordion
        alwaysOpen
        activeKey={expandedItem}
        ...
    >
        ...
    </Accordion>