pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图1

用于 React 的原始和灵活的状态管理

npm i jotai

pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图2
pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图3
pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图4
pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图5
pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图6
pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图7

Jotai 的发音是 “joe-tie”,在日语中意为 “状态”。

你可以在以下内容中尝试现场演示。演示 1 | 演示 2。

Jotai 与 Recoil 有什么不同?

  • 极简的 API
  • 没有字符串键
  • 面向 TypeScript

首先创建一个原始的原子

一个原子代表一段状态。你只需要指定一个初始值,它可以是原始值,如字符串和数字,对象和数组。你可以创建任意多的原始原子。

  1. import { atom } from 'jotai'
  2. const countAtom = atom(0)
  3. const countryAtom = atom('Japan')
  4. const citiesAtom = atom(['Tokyo', 'Kyoto', 'Osaka'])
  5. const mangaAtom = atom({ 'Dragon Ball': 1984, 'One Piece': 1997, Naruto: 1999 })

在你的组件中使用原子

它可以像 React.useState 一样使用。

  1. import { useAtom } from 'jotai'
  2. function Counter() {
  3. const [count, setCount] = useAtom(countAtom)
  4. return (
  5. <h1>
  6. {count}
  7. <button onClick={() => setCount(c => c + 1)}>one up</button>

创建具有计算值的派生原子

通过传递一个 read 函数作为第一个参数,可以从现有的原子中创建一个新的只读原子。get 允许你获取任何原子的上下文值。

  1. const doubledCountAtom = atom((get) => get(countAtom) * 2)
  2. function DoubleCounter() {
  3. const [doubledCount] = useAtom(doubledCountAtom)
  4. return <h2>{doubledCount}</h2>

经验之谈

从多个原子创建一个原子

你可以结合多个原子来创建一个派生原子。

  1. const count1 = atom(1)
  2. const count2 = atom(2)
  3. const count3 = atom(3)
  4. const sum = atom((get) => get(count1) + get(count2) + get(count3))

或者如果你喜欢 fp 模式 …

  1. const atoms = [count1, count2, count3, ...otherAtoms]
  2. const sum = atom((get) => atoms.map(get).reduce((acc, count) => acc + count))

衍生的异步原子

你也可以把读函数变成一个异步函数。

  1. const urlAtom = atom("https://json.host.com")
  2. const fetchUrlAtom = atom(
  3. async (get) => {
  4. const response = await fetch(get(urlAtom))
  5. return await response.json()
  6. }
  7. )
  8. function Status() {
  9. // Re-renders the component after urlAtom changed and the async function above concludes
  10. const [json] = useAtom(fetchUrlAtom)

你可以创建一个可写的派生原子

在第二个参数中指定一个写函数。get 将返回一个原子的当前值。set 将更新一个原子的值。

  1. const decrementCountAtom = atom(
  2. (get) => get(countAtom),
  3. (get, set, _arg) => set(countAtom, get(countAtom) - 1),
  4. )
  5. function Counter() {
  6. const [count, decrement] = useAtom(decrementCountAtom)
  7. return (
  8. <h1>
  9. {count}
  10. <button onClick={decrement}>Decrease</button>

只写原子

就不要定义一个读函数。

  1. const multiplyCountAtom = atom(null, (get, set, by) => set(countAtom, get(countAtom) * by))
  2. function Controls() {
  3. const [, multiply] = useAtom(multiplyCountAtom)
  4. return <button onClick={() => multiply(3)}>triple</button>

异步行动

只要把写函数变成一个异步函数,准备好后再调用 set。

  1. const fetchCountAtom = atom(
  2. (get) => get(countAtom),
  3. async (_get, set, url) => {
  4. const response = await fetch(url)
  5. set(countAtom, (await response.json()).count)
  6. }
  7. )
  8. function Controls() {
  9. const [count, compute] = useAtom(fetchCountAtom)
  10. return <button onClick={() => compute("http://count.host.com")}>compute</button>

安装说明

这个包需要一些同行的依赖,你需要自己安装。

pmndrs/jotai: 👻 React的原始和灵活状态管理 - 图8

https://github.com/pmndrs/jotai