atomWithRefreshAndDefault
这是对 atomWithDefault 的另一种实现
回顾 atomWithDefault 的行为
如你在 atomWithDefault 部分的示例代码中看到的,更新创建的 count2Atom = atomWithDefault((get) => get(count1Atom) * 2)
后,两个原子的关系就断开了。
让我们确认一下发生了什么,
- 点击 "increment count1",然后 count1 是 2,count2 是 4
- 点击 "increment count2",然后 count1 是 2,count2 是 5 (断开连接!!)
更新 count2Atom 后,这些原子就没有关系了。所以,
- 点击 "increment count1",只增加 count1
- 即使你重置 count2Atom,这些依赖关系也永远不会回来
动机
在某些情况下,
- 断开连接和重置后,它们应该回到它们的关系
- 应该根据更新的原始原子重置派生原子
- 我们希望重置所有派生原子,但只想尽可能简单地操作
我们如何实现这些情况呢? 这里有一种声明式的方式来创建一个函数,提供一个可刷新的原子,而不是 atomWithDefault。
const refreshCountAtom = atom(0)const baseDataAtom = atom(1) // 原始数据,例如 base count1Atomconst 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)})