简体   繁体   中英

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>
    );
}

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>

Don't useEffect for update state because it run every update. This will be a performance bug.

You can make the default of the state: the localStorage value if exists else make it blank Array.

Here is your code:

import { useState, useEffect } from "react";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Accordion from "react-bootstrap/Accordion";

export default function Example() {
  let defaultState = JSON.parse(localStorage.getItem("expandedItem")) || new Array();
  let [expandedItem, setExpandedItem] = useState(defaultState);
  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>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM