问题1
const { data: originalMyTrips } = useFetchTrips(data?.myTripIds ?? []);
当 ids 从 [] 变成 [198699] 时,data 会 undefinded,反之却不会
原因:
-
当 ids 从 [] 变成 [198699] 时:
- 新的 queryKey 是 [QUERY_KEYS.trip, "[198699]"]
- 这个 key 在缓存中不存在
- 所以 React Query 会重新执行查询
- 在查询完成前,data 是 undefined
-
当 ids 从 [198699] 变成 [] 时:
- 新的 queryKey 是 [QUERY_KEYS.trip, "[]"]
- 这个 key 在缓存中已经存在(因为之前已经查询过空数组)
- 所以 React Query 会直接使用缓存的值 []
- 不会出现 undefined 的状态
问题2
const { data: originalMyTrips } = useFetchTrips(data?.myTripIds ?? []); const { data: originalAllTrips } = useFetchTrips(data?.allTripIds ?? []);
当有2个请求时不会出现问题1的问题
- 当 ids 从 [] 变成 [198699] 时,originalMyTrips 不会变成 undefined
- 这是因为 allTripIds 总是存在,所以 originalAllTrips 的请求会先执行
- 当 originalAllTrips 的请求完成后,React Query 的缓存机制会更新
- 这时 originalMyTrips 的请求会使用更新后的缓存
问题3
const { data: originalMyTrips } = useFetchTrips(data?.myTripIds ?? [], Boolean(data)); const { data: originalMyTrips } = useFetchTrips(data?.myTripIds ?? [], true);
明明我的Boolean(data) 总是 true,但还是
原因分析:
当使用 方式1 useFetchTrips(data?.myTripIds ?? [], Boolean(data)) 时:
-
初始阶段 (data未加载)
- data = undefined → Boolean(data) = false
- 查询被禁用 (enabled: false)
- originalMyTrips = undefined (默认状态)
-
data加载完成 (myTripIds存在)
- data = 有效值 → Boolean(data) = true
- 查询启用 (enabled: true)
- ids 从 [] 变为 [198699]
- React Query 发现 queryKey 变化 (sortIds 从 "[]" → "[198699]")
- 创建新查询实例,初始状态为 undefined
- 发起网络请求 → 获取数据后更新为 [{…}]
-
当 ids 再次变为空数组
- ids = [] → sortIds = "[]"
- queryKey 再次变化 → 创建新查询实例
- 由于 enabled: true 且 ids 为空,触发空数组查询
- 若未显式处理空数组,可能返回 undefined
方式2 useFetchTrips(data?.myTripIds ?? [], true) 的行为:
- 始终启用查询 (enabled: true)
- 首次加载时 ids = [] (因 data 未加载)
- 直接执行空数组查询 → 返回 []
- data加载后 ids 变为 [198699]
- queryKey 变化 → 发起新查询
- 保留旧数据 ([]) 直到新查询完成
- 没有 enabled 状态切换
- 避免查询实例重建导致的 undefined 状态
graph TD
A[组件挂载] --> B{查询enabled?}
B -->|方式一:否| C[等待data加载]
B -->|方式二:是| D[立即执行空数组查询]
C --> E[data加载完成]
E --> F[执行有效ids查询]
D --> G[缓存空数组结果]
F --> H[缓存有效结果]
G --> I[后续ids变化触发新查询]