3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【覚え書き】Reactでdetailsタグを使用したアコーディオンの開閉状態をlocalstorageに保存する

Last updated at Posted at 2023-04-20

つい最近、仕事でアコーディオンの開いた状態か閉じた状態のどちらかを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を漁ってみる、という学びにもなりました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?