查询数据占位符 Placeholder Query Data
什么是占位数据?
占位数据使查询的行为就像已具有数据一样,类似于initialData选项,但是数据没有被持久化到缓存中。
如果一边有足够多的部分数据(或者完整的 mock 数据)来呈现数据应该呈现的样式,一边同时在后台获取实际数据,那么这就很方便了。
示例:单个博客帖子的查询可以看作是:从博客帖子的父列表中提取"预览"数据,该列表仅包括标题和帖子正文的一小段。 此时,你可能不希望将此部分数据持久化到单个查询的查询结果中,但是它对于在实际查询还在获取整个对象时尽可能快地显示内容布局非常有用。
有几种在需要之前将查询的占位数据提供给缓存的方法:
- 声明式的:
- 为查询提供
placeholderData,以便在查询为空时预填充其缓存
- 为查询提供
- 命令式地:
来自值的占位数据
TypeScript
1function Todos() {2 const result = useQuery({3 queryKey: ["todos"],4 queryFn: () => fetch("/todos"),5 placeholderData: placeholderTodos,6 });7}来自函数的占位数据
如果访问查询的占位数据的过程很繁琐,或者只是不想在每次渲染时都执行这种操作,则可以将该值 memoized 或将 memoized 的函数作为作为placeholderData值传递:
TypeScript
1function Todos() {2 const placeholderData = useMemo(() => generateFakeTodos(), []);3 const result = useQuery({4 queryKey: ["todos"],5 queryFn: () => fetch("/todos"),6 placeholderData,7 });8}来自缓存的占位数据
在某些情况下,你可能需要从另一个查询的缓存结果中来为查询提供占位数据。 这方面的一个比较好的例子是,从博客帖子列表相关的查询中搜索缓存的数据以获取帖子的预览版本,然后将其用作单个文章查询的占位数据:
TypeScript
1function Todo({ blogPostId }) {2 const result = useQuery({3 queryKey: ["blogPost", blogPostId],4 queryFn: () => fetch(`/blogPosts/${blogPostId}`),5 placeholderData: () => {6 // 使用 `blogPosts` 查询中的预览版(较小的)作为这个blogPost查询的占位数据7 return queryClient8 .getQueryData(["blogPosts"])9 ?.find((d) => d.id === blogPostId);10 },11 });12}延伸阅读
如果对于Initial Data和Placeholder Data有困惑的话,请参考此社区内容(英文)