Jotai
状態
Primitive and flexible state management for React
No extra re-renders, state resides within React, you get the full benefits from suspense and concurrent features.
It’s scalable from a simple React.useState replacement to a large scale application with complex requirements.
Introduction
Jotai takes a bottom-up approach to React state management with an atomic model inspired by Recoil. One can build state by combining atoms and renders are optimized based on atom dependency. This solves the extra re-render issue of React context and eliminates the need for the memoization technique.
Core API
Jotai has a very minimal API and is TypeScript oriented. It is as simple to use as React’s integrated
useState
hook, but all state is globally accessible, derived state is easy to implement, and extra re-renders are automatically eliminated.HELLO
import { atom, useAtom } from 'jotai'// Create your atoms and derivativesconst textAtom = atom('hello')const uppercaseAtom = atom((get) => get(textAtom).toUpperCase())// Use them anywhere in your appconst Input = () => {const [text, setText] = useAtom(textAtom)return <input value={text} onChange={(e) => setText(e.target.value)} />}const Uppercase = () => {const [uppercase] = useAtom(uppercaseAtom)return <div>Uppercase: {uppercase}</div>}// Now you have the componentsconst MyApp = () => {return (<><Input /><Uppercase /></>)}
Extra utils
The Jotai package also includes a
jotai/utils
bundle. These functions add support for persisting an atom’s state in localStorage or a URL hash, creating an atom with a set function with redux-like reducers and action types, and more.import { useAtom } from 'jotai'import { atomWithStorage } from 'jotai/utils'// Set the string key and the initial valueconst darkModeAtom = atomWithStorage('darkMode', false)const Page = () => {// Consume persisted state like any other atomconst [darkMode, setDarkMode] = useAtom(darkModeAtom)return (<><h1>Welcome to {darkMode ? 'dark' : 'light'} mode!</h1><button onClick={() => setDarkMode(!darkMode)}>toggle theme</button></>)}
Third-party integrations
There are also additional bundles for each official third-party integration. Immer, Optics, Query, XState, Valtio, Zustand, and Redux. Some integrations provide new atom types with alternate update functions such as
atomWithImmer
while others provide new atom types with two-way data binding for other state management libraries such as atomWithStore
which is bound with a Redux store.0
import { useAtom } from 'jotai'import { atomWithImmer } from 'jotai/immer'// Create a new atom with an immer-based write functionconst countAtom = atomWithImmer(0)const Counter = () => {const [count] = useAtom(countAtom)return <div>count: {count}</div>}const Controls = () => {// setCount === update: (draft: Draft<Value>) => voidconst [, setCount] = useAtom(countAtom)const increment = () => setCount((c) => (c = c + 1))return <button onClick={increment}>+1</button>}