JotaiJotai

Jotai
React 原始而灵活的状态管理

atomWithRefreshAndDefault

这是对 atomWithDefault 的另一种实现

回顾 atomWithDefault 的行为

如你在 atomWithDefault 部分的示例代码中看到的,更新创建的 count2Atom = atomWithDefault((get) => get(count1Atom) * 2) 后,两个原子的关系就断开了。 让我们确认一下发生了什么,

    1. 点击 "increment count1",然后 count1 是 2,count2 是 4
    1. 点击 "increment count2",然后 count1 是 2,count2 是 5 (断开连接!!)

更新 count2Atom 后,这些原子就没有关系了。所以,

  • 点击 "increment count1",只增加 count1
  • 即使你重置 count2Atom,这些依赖关系也永远不会回来

动机

在某些情况下,

  • 断开连接和重置后,它们应该回到它们的关系
  • 应该根据更新的原始原子重置派生原子
  • 我们希望重置所有派生原子,但只想尽可能简单地操作

我们如何实现这些情况呢? 这里有一种声明式的方式来创建一个函数,提供一个可刷新的原子,而不是 atomWithDefault。

const refreshCountAtom = atom(0)
const baseDataAtom = atom(1) // 原始数据,例如 base count1Atom
const dataAtom = atom(
(get) => {
get(refreshCountAtom) // 它在 atomWithRefresh 中引入
return get(baseDataAtom)
},
(get, set, update) => {
set(baseDataAtom, update)
},
)
const atomWithRefreshAndDefault = (refreshAtom, getDefault) => {
const overwrittenAtom = atom(null)
return atom(
(get) => {
const lastState = get(overwrittenAtom)
if (lastState && lastState.refresh === get(refreshAtom)) {
return lastState.value
}
return getDefault(get)
},
(get, set, update) => {
set(overwrittenAtom, { refresh: get(refreshAtom), value: update })
},
)
}
// 这是 `atomWithDefault((get) => get(count1Atom) * 2)` 的替代品
const refreshableAtom = atomWithRefreshAndDefault(
refreshCountAtom,
(get) => get(dataAtom) * 2,
)
// 你可以通过更新一个原子来重置
const resetRootAtom = atom(null, (get, set) => {
set(refreshCountAtom, get(refreshCountAtom) + 1)
})