You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jotai:如何更新异步可加载原子以重新获取数据?

解决Jotai中重新获取async atom数据的问题

问题原因

你用loadable()包装的async atom是只读衍生atom,所以useAtom(loadableAtom)返回的第二个参数(set函数)类型为never,无法调用,这就是报错的核心原因。

解决方案

要实现主动重新获取数据,需要把异步逻辑改成可触发的写法,以下两种方案可以直接使用:

方案1:拆分数据存储与刷新逻辑

import { atom, useAtom } from 'jotai';

// 存储交易数据的可写atom
const transactionsAtom = atom<Transaction[] | null>(null);

// 触发数据刷新的action atom
const refreshTransactionsAtom = atom(
  null,
  async (_get, set) => {
    const res = await fetch("http://localhost:3000/api/transactions");
    const data = await res.json();
    set(transactionsAtom, data);
  }
);

// 组件内使用
const [transactions] = useAtom(transactionsAtom);
const [, refreshTransactions] = useAtom(refreshTransactionsAtom);

// 调用刷新:比如按钮点击事件
// <button onClick={refreshTransactions}>刷新数据</button>

方案2:保留loadable状态的刷新方案

如果想保留loadable提供的加载/错误状态,可以通过添加刷新信号触发异步逻辑重新执行:

import { atom, useAtom, loadable } from 'jotai';

// 刷新信号atom:用递增数字触发重新请求
const refreshSignalAtom = atom(0);

// 依赖刷新信号的async atom,信号变化时重新请求
const asyncTransactionsAtom = atom(async (get) => {
  get(refreshSignalAtom); // 绑定刷新信号
  const res = await fetch("http://localhost:3000/api/transactions");
  return res.json();
});

// 包装成loadable atom获取状态
const loadableTransactionsAtom = loadable(asyncTransactionsAtom);

// 组件内使用
const [transactions] = useAtom(loadableTransactionsAtom);
const [refreshSignal, setRefreshSignal] = useAtom(refreshSignalAtom);

// 触发刷新:更新信号值
const refreshTransactions = () => setRefreshSignal(prev => prev + 1);

关键提示

  • 禁止直接对loadable()返回的atom调用set函数,它是只读衍生atom
  • 实现刷新的核心是给异步逻辑设置可触发的依赖信号,或是将数据存储在可写atom中主动更新

内容的提问来源于stack exchange,提问作者Snickers03

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:25:13