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.