つい最近、仕事でアコーディオンの開いた状態か閉じた状態のどちらかをlocalstorageに保存して、次回アクセスしたときも前回の状態のまま表示させる、ということをやったのでそれの備忘録です。
index.jsx
import {useEffect, useState} from "react"
export const Accordion = () => {
const [isOpen, setIsOpen] = useState(
// localstorageに保存された真偽値で判定。最初は何も入っていないのでfalse
localStorage.getItem("openState") === "true" ? true : false
)
const toggleAccordion = (e) => {
e.preventDefault()
// summaryをクリックし、falseだったらtrueを、trueだったらfalseを返す
setIsOpen((prev)=> !prev)
}
useEffect(() => {
// toggleAccordionでisOpenの値が変更されたので変更された真偽値をlocalstorageに保存
localStorage.setItem("openState", JSON.stringify(isOpen))
}, [isOpen])
return (
<details open={isOpen}>
<summary onClick={toggleAccordion}>少年漫画ランキング詳細</summary>
<ol>
<li>ワンピース</li>
<li>呪術廻戦</li>
<li>東京卍リベンジャーズ</li>
<li>鬼滅の刃</li>
<li>葬送のフリーレン</li>
</ol>
</details>
)
}
demo
ちょっとハマったこと
summaryをクリックしたタイミングでlocalstorageに値を保存はされているが、アコーディオンが開かない。
もう一度クリックするとアコーディオンは開くけど、保存された値はfalseになっている、という状態になりました(開いた状態の値はtrueになってなければいけない)
どうやらtoggleAccordion
に.preventDefault()
を使わないと正しく動かないみたいで、これを解決するために数時間費やしました。
参考
<details> open attribute not synchronised
ちょっとハマって探しても見つからなかったら公式リポジトリのissueを漁ってみる、という学びにもなりました。