DevTools 调试工具
@tanstack/react-query-devtools 的安装、使用与核心功能:查看缓存状态、query 详情、网络请求时间线。
#type / howto
#status / evergreen
#tech / dev / frontend
#resource / react
[!info] related notes
- 前置: TanStack Query 服务端状态
- 所属 MOC: TanStack Query 知识地图
- 关联: gcTime vs staleTime
- 关联: QueryClient 配置策略
DevTools 调试工具
安装
npm install @tanstack/react-query-devtools
基本配置
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
{/* 生产环境不显示 */}
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}
仅开发环境
{process.env.NODE_ENV === 'development' && (
<ReactQueryDevtools initialIsOpen={false} />
)}
核心功能
1. Query 列表
左侧面板显示所有活跃和非活跃的 query:
- 绿色圆点:数据新鲜(fresh)
- 黄色圆点:数据过期(stale)
- 灰色圆点:非活跃(inactive)
- 蓝色圆点:正在获取(fetching)
2. Query 详情
点击任意 query 查看:
| 字段 | 说明 |
|---|---|
| Query Key | 缓存键 |
| Data | 缓存的数据 |
| Data Updated | 数据最后更新时间 |
| Status | success / error / pending |
| Fetch Status | fetching / paused / idle |
| Observer Count | 有多少组件在监听 |
| Stale Time | 配置的新鲜时间 |
| Cache Time | 配置的缓存保留时间 |
| Inactive | 是否有活跃订阅者 |
3. 操作按钮
- Refetch:手动触发重新获取
- Invalidate:标记为 stale
- Reset:重置到初始状态
- Remove:从缓存中删除
- Copy:复制 query 数据到剪贴板
- View query in queryFn:跳转到代码(需要 source map)
4. Mutation 列表
查看所有 mutation 的状态和历史。
实用调试场景
场景 1:数据不更新
症状:修改了数据但 UI 没变
排查:
1. 打开 DevTools
2. 找到对应的 query
3. 检查 Status:是否 stale?
4. 检查 Observer Count:是否有组件在监听?
5. 检查 Data Updated:数据什么时候更新的?
场景 2:重复请求
症状:同一个接口请求了多次
排查:
1. 打开 DevTools
2. 检查是否有多个相同 queryKey 的 query
3. 如果有 → 说明 key 不一致
4. 检查 Observer Count → 可能有多个组件监听同一个 query
场景 3:缓存泄漏
症状:内存持续增长
排查:
1. 打开 DevTools
2. 检查 inactive 的 query 数量
3. 如果很多 → gcTime 可能太大,或者 key 不断变化产生新条目
场景 4:乐观更新不生效
症状:mutation 后 UI 闪回旧数据
排查:
1. 检查 mutation 的 onMutate 是否执行
2. 检查 onError 是否被触发(可能请求失败,回滚了)
3. 检查 onSettled 的 invalidateQueries 是否覆盖了乐观数据
自定义位置
// 默认在左下角
<ReactQueryDevtools initialIsOpen={false} />
// 放在右下角
<ReactQueryDevtools
initialIsOpen={false}
position="bottom-right"
/>
// 按钮位置
<ReactQueryDevtools
initialIsOpen={false}
buttonPosition="bottom-right"
/>
生产环境使用
// 仅在特定条件下启用(如管理员用户)
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
function App() {
const isAdmin = useIsAdmin();
return (
<QueryClientProvider client={queryClient}>
<YourApp />
{isAdmin && <ReactQueryDevtools initialIsOpen={false} />}
</QueryClientProvider>
);
}
替代方案
代码中调试
// 在组件中监听 query 状态变化
const { data, status, fetchStatus, isStale, isFetching } = useQuery({
queryKey: ['user', id],
queryFn: () => fetchUser(id),
});
useEffect(() => {
console.log('[Query Debug]', {
key: ['user', id],
status,
fetchStatus,
isStale,
isFetching,
dataUpdatedAt: data ? new Date().toISOString() : null,
});
}, [data, status, fetchStatus, isStale, isFetching]);
QueryClient 事件监听
const queryClient = new QueryClient();
// 监听所有 query 的成功
queryClient.getQueryCache().subscribe((event) => {
if (event.type === 'updated' && event.action.type === 'success') {
console.log('[Query Success]', event.query.queryKey, event.action.data);
}
});
// 监听所有 query 的失败
queryClient.getQueryCache().subscribe((event) => {
if (event.type === 'updated' && event.action.type === 'error') {
console.error('[Query Error]', event.query.queryKey, event.action.error);
}
});
常见错误
DevTools 不显示
// ❌ 没放在 QueryClientProvider 内
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
<ReactQueryDevtools /> {/* 外面了 */}
// ✅ 放在 Provider 内
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools />
</QueryClientProvider>
忘记安装 devtools 包
# react-query 和 devtools 是分开的包
npm install @tanstack/react-query
npm install @tanstack/react-query-devtools # 需要单独安装