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
相关产品推荐
相关产品推荐

