---
id: query-freshness
track: learn
product: query
locale: zh-CN
order: 10
revision: 2
sourceCheckedOn: "2026-08-03"
versionRange: "Query ^5"
verifiedAgainst: "@tanstack/react-query@5.101.4"
contentModel: 2
prerequisites:
  - "理解 Query 缓存与 queryKey"
sourceRefs:
  - "https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults"
  - "https://tanstack.com/query/latest/docs/framework/react/guides/query-options"
---

# 先定义数据何时算新鲜

> 分清 staleTime 与 gcTime，用共享 queryOptions 把查询键、请求函数和时间策略放在一起。

**Outcome:** 能根据业务变化频率设置新鲜期，并解释为什么垃圾回收时间不能阻止后台重新获取。

## 新鲜与保留是两个问题

staleTime 决定数据多久仍可被视为新鲜；gcTime 决定没有观察者的 inactive 查询在缓存中保留多久。默认缓存数据立即 stale，inactive 查询通常在五分钟后回收。增加 gcTime 不会让数据变新鲜。

## 把时间策略放进查询契约

queryOptions 在运行时只返回传入配置，但会保留 queryKey 与 queryFn 的类型关系。Loader 预取、组件读取和写入缓存都应复用这一契约，避免同一资源出现不同时间策略。

> **Note:** 时间值来自数据变化和用户容忍度，不要为了减少请求盲目设成 Infinity。

File: `src/features/issues/queries.ts`

```ts
import { queryOptions } from '@tanstack/react-query'

export const issueOptions = (issueId: string) => queryOptions({
  queryKey: ['issues', 'detail', issueId] as const,
  queryFn: () => getIssue(issueId),
  staleTime: 60_000,
  gcTime: 10 * 60_000,
})
```

## 实践与验证

### 完成检查点

能根据业务变化频率解释 staleTime，并区分新鲜度与非活跃缓存的回收时间。

### 动手练习

为 Issue 列表、详情和静态优先级字典分别定义新鲜度策略，并说明差异。

### 验证方法

使用 Devtools 观察 fresh、stale、inactive 三种状态，并验证窗口聚焦行为符合策略。

### 常见错误

- 用 gcTime 控制是否重新请求数据。
- 为解决重复请求而关闭所有自动重新获取。

## Official sources

- https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults
- https://tanstack.com/query/latest/docs/framework/react/guides/query-options
