可重置 atom
可重置 atom 是 Jotai 在其核心库基础上扩展出来的一个自带默认功能的 atom。Jotai 在jotai/utils
库里定义了一系列相应的构建函数和 Hook 来支持可重置 atom 的使用。
顾名思义,可重置 atom 可以记录其被创建时的初始值,并且可以使用一个特殊值来使 atom 的值恢复为初始值。为了达到这个目的,jotai/utils
里定义了一个特殊值RESET
,这是一个symbol
类型的的值,它存在的唯一目的就是向可重置 atom 传递重置信号。
可重置 atom 时使用jotai/utils
中提供的atomWithReset
函数构建的,这个函数的使用跟构建 atom 使用的atom
函数相像,其签名如下。
function atomWithReset<Value>(
initialValue: Value,
): WritableAtom<Value, SetStateAction<Value> | type RESET>
可重置 atom 可以像普通 atom 一样通过useAtom
Hook 使用。例如:
const TodoListAtom = atomWithReset([]);
const TodoList = () => {
const [todos, setTodos] = useAtom(TodoListAtom);
return (
<div>
{todos.map((todo, index) => (
<div key={index}>{todo}</div>
))}
<div>
<button onClick={() => setTodos(RESET)}>Reset</button>
</div>
</div>
);
};
在这个示例中,通过向 atom 的更新方法传入RESET
信号,就可以使 atom 的值恢复到初始值。
为了方便重置操作,Jotai 还提供了一个useResetAtom
Hook,可以直接返回一个可重置 atom 的重置方法。现在上面这个示例可以更改为以下形式。
const TodoListAtom = atomWithReset([]);
const TodoList = () => {
const todos = useAtomValue(TodoListAtom);
const resetTodoList = useResetAtom(TodoListAtom);
return (
<div>
{todos.map((todo, index) => (
<div key={index}>{todo}</div>
))}
<div>
<button onClick={() => resetTodoList()}>Reset</button>
</div>
</div>
);
};
带有默认值的 atom
带有默认值的 atom 是可重置 atom 的一个延伸使用方式。带有默认值的 atom 使用atomWithDefault
函数创建,其创建形式与只读 atom 的创建十分相似。带有默认值的 atom 可以基于另一个原始 atom 创建它的初始值,并且在没有更新它的值的情况下,其值会随着它所依赖的原始值变化。但是如果调用了它的更新方法,它将与其依赖的 atom 解耦,直到它被重置为止。
以下是带有默认值的 atom 使用示例,读者可以自行尝试其执行效果。
const counter1Atom = atom(1);
const counter2Atom = atomWithDefault((get) => get(counter1Atom) * 3);
const Demo = () => {
const [c1, setCounter1] = useAtom(counter1Atom);
const [c2, setCounter2] = useAtom(counter2Atom);
return (
<div>
<div>Counter 1: {c1}</div>
<div>Counter 2: {c2}</div>
<div>
<button onClick={() => setCounter1((c) => c + 1)}>
Increment Counter 1
</button>
<button onClick={() => setCounter2((c) => c + 3)}>
Increment Counter 2
</button>
<button onClick={() => setCounter2(RESET)}>Reset Counter 2</button>
</div>
</div>
);
};
带有默认值的 atom 同样可以使用useResetAtom
来创建快速重置方法。