题目
一个 DApp 的刷新策略各不相同:有的页面把每个查询都设为 1 秒轮询,有的页面只在进入时拉一次数据,交易完成后又有页面长时间不更新。请给出一套可维护的刷新策略,并说明订阅与轮询的边界。
考察目标
- 轮询、订阅与显式失效三种刷新方式的适用位置。
- 按数据时效分组设置策略的做法。
- 订阅清理、断线回退与后台标签页的处理边界。
按数据时效分组,在轮询、订阅与显式失效之间取舍,并处理后台标签页与断线补扫。
一个 DApp 的刷新策略各不相同:有的页面把每个查询都设为 1 秒轮询,有的页面只在进入时拉一次数据,交易完成后又有页面长时间不更新。请给出一套可维护的刷新策略,并说明订阅与轮询的边界。
wagmi 的刷新能力分布在三处:查询侧的 refetchInterval 等 TanStack Query 选项决定定时重取;useBlockNumber 的 watch 参数监听块高变化,可以把这类变化当作失效的触发点;useWatchContractEvent 提供事件订阅,文档说明 poll 在 WebSocket 客户端下默认为 false、在非 WebSocket 客户端下默认为 true。TanStack Query 指南把失效定义为把查询数据标记为过期并重取已渲染的查询。因此刷新策略的落点是按数据时效分组,再为每组选择轮询、订阅或显式失效。实现差异与工程取舍见深入回答。
import { useEffect } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useBalance, useBlockNumber, useConnection } from "wagmi";
export function Balance() {
const queryClient = useQueryClient();
const { address, chainId } = useConnection();
const { data: blockNumber } = useBlockNumber({ chainId, watch: true });
const { data: balance, queryKey } = useBalance({ address, chainId });
useEffect(() => {
if (!address || blockNumber === undefined) return;
void queryClient.invalidateQueries({ queryKey });
}, [address, blockNumber, queryClient, queryKey]);
return <div>{balance?.formatted ?? "—"}</div>;
}
示例省略了加载与错误状态处理,思路取自 wagmi TanStack Query 指南的余额失效示例。
发现这道题有问题? 反馈此题