自己用 useEffect 加 fetch 管理请求时,加载态、错误态、竞态、缓存、重试全都要手写,页面一多就复制粘贴。React Query(TanStack Query)换了个视角:远端数据本质是有缓存的服务端状态。useQuery 一声明,它自动在组件挂载时请求、缓存结果、焦点失焦时按需刷新,还提供加载与错误状态。
它也不是银弹:若你的列表有大量本地增删改的交互状态,那部分仍属于客户端状态,应该放 useState 或状态管理库里。它只解决取数一层的标准化:键值即缓存标识,配合 queryKey 设计与 mutation 失效策略,能优雅做到保存后自动刷新列表。
// useQuery 的思想拆解(不引依赖,体会其缓存模型) var cache = {}; function useQuery(key, fetcher) { var entry = cache[key] = cache[key] || { data: undefined, loading: true, error: null }; var _a = React.useState(0); var force = _a[1]; var rerender = function () { force(function (n) { return n + 1; }); }; React.useEffect(function () { if (entry.data !== undefined) return; // 命中缓存就不再请求 fetcher().then(function (d) { entry.data = d; entry.loading = false; rerender(); }) .catch(function (e) { entry.error = e; entry.loading = false; rerender(); }); }, []); return { data: entry.data, loading: entry.loading, error: entry.error }; } // 另一个相同 key 的组件直接命中缓存,不再重复请求 function User(_a) { var id = _a.id; var q = useQuery('user-' + id, function () { return fetch('/api/user/' + id).then(function (r) { return r.json(); }); }); return q.loading ? '加载中' : q.data.name; }