占位符

占位符允许查询的状态表现得好像已经有数据一样,类似于 initialData 选项,但数据不会持久保存到缓存中。

当我们使用 placeholderData 选项时,查询将不会处于 pending 状态, 它将以 success 状态开始,因为我们有数据要显示 , 即使该数据只是占位符数据。为了将其与真实数据区分开来,我们还将在查询结果上将isPlaceholderData标志设置为true

占位符数据作为值

const userQuery = useQuery({
  queryKey: ["users", id],
  queryFn: async () => {
    await sleep(2000);
    return fetch(`http://localhost:3000/${id}`).then((res) => res.json());
  },
  placeholderData: { id: 1, name: "John Doe", email: "alice@example.com" }
});

占位符数据记忆化

如果占位符数据的计算过程很繁琐,或者你不想每次在渲染时都执行此操作,那么你可以记住该值

const placeholderData = useMemo(() => ({ id: 1, name: "John Doe", email: "alice@example.com" }), []);
const userQuery = useQuery({
  queryKey: ["users", id],
  queryFn: async () => {
    await sleep(2000);
    return fetch(`http://localhost:3000/${id}`).then((res) => res.json());
  },
  placeholderData
});

函数

placeholderData 也可以是一个函数,你可以通过访问上一个成功查询到的数据和和查询元信息,当 queryKey 发生变化时,例如从["users",1]变为["users",2]时,我们可以继续显示旧数据,而不是在数据从一个查询转换到下一个查询时显示加载状态的 UI。

const userQuery = useQuery({
  queryKey: ["users", id],
  queryFn: async () => {
    await sleep(2000);
    return fetch(`http://localhost:3000/${id}`).then((res) => res.json());
  },
  placeholderData: (previousData, previousQuery) => previousData
});

来自缓存的占位数据

在某些情况下,你可以从另一个查询结果的缓存中获取数据提供占位符数据。

const userQuery = useQuery({
  queryKey: ["users", id],
  queryFn: async () => {
    await sleep(2000);
    return fetch(`http://localhost:3000/${id}`).then((res) => res.json());
  },
  placeholderData: (previousData) => {
    return queryClient.getQueryData(["users"])?.find((user) => user.id === previousData.id + 1);
  }
});

最后更新于

这有帮助吗?