跳转到内容

Immer

你需要安装 immerjotai-immer 才能使用此功能。

npm install immer jotai-immer

atomWithImmer 创建一个与常规 atom 类似的新原子,但使用了不同的 writeFunction。在这个包中,我们没有只读原子,因为这些函数的核心在于 immer 的 produce(可变性)功能。 writeFunction 的签名为 (get, set, update: (draft: Draft<Value>) => void) => void

import { useAtom } from 'jotai'
import { atomWithImmer } from 'jotai-immer'
const countAtom = atomWithImmer({ value: 0 })
const Counter = () => {
const [count] = useAtom(countAtom)
return <div>count: {count.value}</div>
}
const Controls = () => {
const [, setCount] = useAtom(countAtom)
// setCount === update : (draft: Draft<Value>) => void
const inc = () =>
setCount((draft) => {
++draft.value
})
return <button onClick={inc}>+1</button>
}

查看 atomWithImmer 的示例:

Open in StackBlitz

withImmer 接收一个原子并返回一个派生原子,与 atomWithImmer 一样使用了不同的 writeFunction

import { useAtom, atom } from 'jotai'
import { withImmer } from 'jotai-immer'
const primitiveAtom = atom({ value: 0 })
const countAtom = withImmer(primitiveAtom)
const Counter = () => {
const [count] = useAtom(countAtom)
return <div>count: {count.value}</div>
}
const Controls = () => {
const [, setCount] = useAtom(countAtom)
// setCount === update : (draft: Draft<Value>) => void
const inc = () =>
setCount((draft) => {
++draft.value
})
return <button onClick={inc}>+1</button>
}

查看 withImmer 的示例:

Open in StackBlitz

这个 hook 接收一个原子,并将该原子的 writeFunction 替换为类似 immer 的新 writeFunction,与前面的辅助函数类似。

import { atom } from 'jotai'
import { useImmerAtom } from 'jotai-immer'
const primitiveAtom = atom({ value: 0 })
const Counter = () => {
const [count] = useImmerAtom(primitiveAtom)
return <div>count: {count.value}</div>
}
const Controls = () => {
const [, setCount] = useImmerAtom(primitiveAtom)
// setCount === update : (draft: Draft<Value>) => void
const inc = () =>
setCount((draft) => {
++draft.value
})
return <button onClick={inc}>+1</button>
}

最好不要将 withImmeratomWithImmeruseImmerAtom 一起使用,因为它们已经提供了类似 immer 的 writeFunction,不需要再创建新的。

如果你只需要 useImmerAtom 的 setter 部分,可以使用 useSetImmerAtom

查看 useImmerAtom 的示例:

Open in StackBlitz

Open in StackBlitz