iTranslated by AI
Managing Themes with Jotai
Sometimes you want to save dark mode settings on the browser side, right?
In such cases, I'll introduce Jotai's atomWithStorage, which is quite convenient.
atomWithStorage
Usage is not much different from a regular atom. It can be used as follows.
By default, it uses localStorage to save values, so the state is maintained even after the page is closed.
import { atomWithStorage } from 'jotai/utils'
export const isDarkModeAtom = atomWithStorage<boolean>(
`isDarkMode`, // Specify the key
false // Initial value
)
Since Jotai is basically designed to hold values on the client side, you need to specify use client in Next.js.
'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
Just as described in the official documentation, you can also delete values using 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>
</>
)
}
Parameters
The parameters that can be specified are as follows; key and initialValue are as explained earlier.
atomWithStorage([key],[initialValue],[storage],[options])
You can specify a boolean value for options as follows, but I don't quite understand its intended use yet.
According to the official documentation, it is a "boolean value indicating whether to get the item from storage on initialization." Does this specify the behavior when a RESET is performed, for example?
I will add more information here once I understand it better.
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 }
)
By specifying storage, you can customize the behavior when values are retrieved or set.
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.
Summary
Initially, I was thinking about using localStorage and then having to update the screen by setting it in a state, but I'm sharing this because I was able to achieve it in a single line with Jotai.
Thank you, Jotai.
Discussion