初始化查询数据

使用 initialData 预填充查询

有时,你的应用中可能已经有查询的初始数据,你可以直接将其其提供给查询,当设置 initialData 选项后,查询会跳过初始加载状态!

initialData 会保留在缓存中,因此不建议为此选项提供占位符或不完整的数据,而应使用 placeholderData

const query = useQuery({
  queryKey: ["users"],
  queryFn: () => fetch("/users"),
  initialData: initialUsers
});

stale 和 initialDataUpdatedAt

默认情况下,initialData 被视为 stale,这也意味着它将影响 staleTime 选项对其的解释方式。

  • 如果你使用 initialSata 配置查询观察器,并且使用默认的 staleTime(默认值 0),则查询将在挂载时立即获取数据:

const query = useQuery({
  queryKey: ["users"],
  queryFn: () => fetch("/users"),
  initialData: initialUsers
});
  • 如果你使用 initialData1000msstaleTime 配置,则数据在 1000ms 内被视为新鲜的,就像是刚从服务器中获取到的一样。

const query = useQuery({
  queryKey: ["users"],
  queryFn: () => fetch("/users"),
  initialData: initialUsers,
  staleTime: 1000
});
  • 如果你的 initialData 不是全新的怎么办?使用一个名为 initialDataUpdateAt 的选项。此选项允许你传递 initialData 本身上次更新时的时间戳(ms),例如 Date.now()提供的时间戳。

const query = useQuery({
  queryKey: ["todos"],
  queryFn: () => fetch("/todos"),
  initialData: initialTodos,
  staleTime: 60 * 1000, // 1 minute
  // 这可以是10秒前,也可以是10分钟前
  initialDataUpdateAt: initialTodoUpdatedTimestamp // eg: 1608412420052
});

初始数据函数

const query = useQuery({
  queryKey: ["todos"],
  queryFn: () => fetch("/todos"),
  initialData: () => getExpensiveTodos()
});

来自缓存的初始数据

在某些情况下,你可以从另一个查询的缓存数据中获取初始数据。例如,从待办事项列的缓存中搜索单个待办事项,然后将其作为单个待办事项的初始数据:

const query = useQuery({
  queryKey: ["todo", id],
  queryFn: () => fetch("/todos"),
  initialData: () => {
    return queryClient.getQueryData(["todos"])?.find((d) => d.id === id);
  }
});

来自 initialDataUpdateAt 从缓存中获取初始数据

从缓存中获取数据可能意味着数据已经过期了,建议将查询的 dataUpdateAt 传递给 initialDataUpdateAt ,而不是使用人为的 staleTime 来组织查询的重新获取,无论是否提供初始数据,这都会为查询实例提供所需的所有信息,以确定是否及何时需要重新获取查询。

const query = useQuery({
  queryKey: ["todos", id],
  queryFn: () => fetch("/todos"),
  initialData: () => {
    return queryClient.getQueryData(["todos"])?.find((d) => d.id === id);
  },
  initialDataUpdateAt: () => {
    queryClient.getQueryState(["todos"])?.dataUpdatedAt;
  }
});

来自缓存的条件初始数据

如果你用来查找初始数据的缓存已经过时了,此时你应该从服务器获取新的数据。而不是使用缓存中陈旧的数据。

const query = useQuery({
  queryKey: ["todos", id],
  queryFn: () => fetch(`/todos/${todoId}`),
  initialData: () => {
    return queryClient.getQueryData(["todos"])?.find((d) => d.id === id);
  },
  initialData: () => {
    const state = queryClient.getQueryState(["todos"]);

    // 如果查询存在并且数据不超过1分钟
    if (state && Date.now() - state.dataUpdatedAt < 60 * 1000) {
      return state.data.find((d) => d.id === id);
    }
    // 否则,返回 undefined 并且硬加载状态获取
  }
});

最后更新于

这有帮助吗?