题目
一个授权按钮在交易上链后没有刷新额度显示,另一些页面反而因为全局轮询产生大量请求。请说明从写操作到缓存更新的正确链路,并给出失效范围的设计方式。
考察目标
- 写操作返回值与状态更新的差距。
- 回执等待与成功条件判断。
- 失效范围与刷新策略设计。
说明从交易哈希到回执的等待链路、失效范围的设计,以及乐观更新与回滚的处理。
一个授权按钮在交易上链后没有刷新额度显示,另一些页面反而因为全局轮询产生大量请求。请说明从写操作到缓存更新的正确链路,并给出失效范围的设计方式。
useWriteContract 的 mutation 成功时返回交易哈希,此时链上状态变化尚未确认;把哈希交给 useWaitForTransactionReceipt 等待结果,确认成功后再更新页面。确认成功后用 invalidateQueries 失效相关查询,可以使用 hook 返回的 queryKey 做定点失效,也可以按前缀批量失效。实现差异与工程取舍见深入回答。
// 省略上下文:abi、address、owner、spender 来自当前链与账户配置;加载态与错误提示未展开。
const queryClient = useQueryClient();
const { mutate: writeContract, data: hash } = useWriteContract();
const { isSuccess } = useWaitForTransactionReceipt({ hash });
const { queryKey: allowanceQueryKey } = useReadContract({
abi,
address,
functionName: "allowance",
args: [owner, spender],
});
useEffect(() => {
if (isSuccess) {
// 用读取 hook 的完整 queryKey 定点失效,避免刷新其他账户或链。
void queryClient.invalidateQueries({ queryKey: allowanceQueryKey });
}
}, [isSuccess, queryClient, allowanceQueryKey]);
发现这道题有问题? 反馈此题