📚

jotaiでテーマを管理する

2023/12/24に公開

ダークモードの設定をブラウザ側に保管しておきたい時ってありますよね。
そんな時に便利なjotaiのatomWithStorageを紹介します。

atomWithStorage

https://jotai.org/docs/utilities/storage#atomwithstorage

通常のatomの使い方とあまり変わらず。以下のような感じで使えます。
デフォルトでlocalStorageを使って値を保存してくれるので、ページを閉じても値が保持されます。

atoms.tsx
import { atomWithStorage } from 'jotai/utils'

export const isDarkModeAtom = atomWithStorage<boolean>(
  `isDarkMode`,  //keyを指定する
  false  //初期値
)

jotaiは基本的にクライアント側で値を保持するためのものなので、nextjsではuse clientを指定する必要があります。

page.tsx
'use client'
import { useAtom } from 'jotai'
import { isDarkModeAtom } from './atoms'

export default function Page() {
  const [isDarkMode, setIsDarkMode] = useAtom(isDarkModeAtom)
    
  setDarkMode(value: boolean) {
    setIsDarkMode(value)
  }
    
  return (
    <>
      <h1>Welcome to {darkMode ? 'dark' : 'light'} mode!</h1>
      <button onClick={() => setDarkMode(!darkMode)}>toggle theme</button>
    </>
  )
}

リセット

公式の記載そのままですが、RESETを使って削除も可能

import { useAtom } from 'jotai'
import { atomWithStorage, RESET } from 'jotai/utils'

const textAtom = atomWithStorage('text', 'hello')

const TextBox = () => {
  const [text, setText] = useAtom(textAtom)

  return (
    <>
      <input value={text} onChange={(e) => setText(e.target.value)} />
      <button onClick={() => setText(RESET)}>Reset (to 'hello')</button>
    </>
  )
}

パラメータ

指定できるパラメータは以下で、keyとinitialValueは先ほど説明した通りです。

atomWithStorage([key],[initialValue],[storage],[options])

optionsには以下のようにしてbool値を指定できますが、あまり用途がわかっていません。
公式の文章をGoole翻訳すると「初期化時にストレージから項目を取得するかどうかを示すブール値」ということなので、RESETをかけたときとかの処理を指定するものでしょうか?
後々わかれば追記します。

options (optional): an object with the following properties:

  • getOnInit (optional): A boolean value indicating whether to get item from storage on initialization.
export const isDarkModeAtom = atomWithStorage<boolean>(
    `isDarkMode`,
    false,
    undefined
    { unstable_getOnInit: true }
)

storageを指定すると、値が取得されるときやセットされるときの動作をカスタマイズ出来ます。

storage (optional): an object with the following methods:

  • getItem(key, initialValue) (required): Reads an item from storage, or falls back to the intialValue
  • setItem(key, value) (required): Saves an item to storage
  • removeItem(key) (required): Deletes the item from storage
  • subscribe(key, callback, initialValue) (optional): A method which subscribes to external storage updates.

まとめ

初めはlocalStrageを使って、値をセットしたら画面も更新しないといけないので、Stateにセットしてとか考えていたのですが、jotai使って一行でできたので紹介しました。
ありがとうjotai。

Discussion