可刷新 atom

可刷新 atom 其实也是上一节中可重置 atom 中的一种,将其单独拿出来讲述的原因是它在自动更新数据方面有很特殊而且重要的用途,有必要单独放置一节来提醒读者注意使用。

可刷新 atom 是使用atomWithRefresh函数定义的,有两种定义形式,一种是不接受更新传入的值,一种可以接受传入的值。其定义形式的签名如下。

// 不接受传入值,仅刷新read方法。
function atomWithRefresh<Value>(
  read: Read<Value, [], void>
): WritableAtom<Value, [], void>;

// 接受传入的值,可以根据传入的值来决定atom内容的更新或者调用read方法完成刷新。
function atomWithRefresh<Value, Args extends unknown[], Result>(
  read: Read<Value, Args, Result>,
  write: Write<Value, Args | [], Result | void>
): WritableAtom<Value, Args | [], Result | void>;

从可刷新 atom 的创建函数的签名可以看出来,可刷新 atom 不使用可重置 atom 中用来重置 atom 值的信号RESET。在使用useAtom来访问这个 atom 的时候,可以直接使用不带参数的set方法直接使其重新执行read方法来刷新 atom 中保持的值。

以下通过一个简单的示例来说明可刷新 atom 的使用。

const commentsAtom = atomWithRefresh(async () => {
  const comments = await fetch("/comments");
  return comments.json();
});

const Comments = () => {
  const [comments, refresh] = useAtom(commentsAtom);

  return (
    <div>
      <button onClick={() => refresh()}>Refresh</button>
      <ul>
        {comments.map((comment) => (
          <li key={comment.id}>{comment.content}</li>
        ))}
      </ul>
    </div>
  );
};

Tip

是的,你没有看错,Jotai支持直接将异步函数作为atom的初始化函数使用。

如果给可刷新 atom 定义了写入方法,那么在调用其更新方法的时候,就需要注意参数的传递了,要防止调用了不正确的更新方法,比如原本需要更新值,却执行了刷新。