You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Query v5 useQuery中initialData与placeholderData的区别及适用场景

React Query v5: 区分useQuery的initialData与placeholderData

核心差异

  • 缓存交互:initialData 会被写入Query缓存,相当于给指定queryKey预存了一份有效数据;placeholderData 只是临时UI填充值,不会修改缓存内容。
  • 加载状态:使用initialData时,isLoading会直接返回false——因为缓存已有初始数据,组件会优先渲染它,同时后台静默执行queryFn刷新数据;使用placeholderData时,isLoading保持true,因为实际请求仍在进行中。
  • 优先级:如果缓存中已有queryKey对应的有效数据,initialData会被忽略;placeholderData不受缓存状态影响,只要请求处于加载阶段就会生效。

适用场景

  • initialData:适合你拥有持久化本地数据(比如localStorage存储的用户信息)、或从父组件传递的已知初始值,希望直接将其作为缓存的起始状态,避免首次加载时的空白UI。
  • placeholderData:适合需要临时填充UI的场景(比如模拟列表结构的占位内容、骨架屏替代数据),让用户感知不到加载空白,但最终数据仍依赖请求返回,且不想污染缓存。

实用示例

1. initialData:用本地缓存初始化用户信息

import { useQuery } from '@tanstack/react-query';

const fetchUser = async () => {
  const res = await fetch('/api/user');
  return res.json();
};

function UserProfile() {
  // 从localStorage读取之前保存的用户数据
  const savedUser = JSON.parse(localStorage.getItem('user') || 'null');

  const { data: user, isFetching } = useQuery({
    queryKey: ['user'],
    queryFn: fetchUser,
    initialData: savedUser,
  });

  // 这里isLoading是false,直接渲染本地数据,isFetching表示后台正在刷新
  return (
    <div>
      {isFetching && <p>正在刷新用户信息...</p>}
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}

2. placeholderData:列表加载时的临时占位内容

import { useQuery } from '@tanstack/react-query';

const fetchPosts = async () => {
  const res = await fetch('/api/posts');
  return res.json();
};

function PostList() {
  // 模拟列表结构的临时占位数据
  const placeholderPosts = [
    { id: 'temp-1', title: '加载中...', content: '请稍候,内容即将加载' },
    { id: 'temp-2', title: '加载中...', content: '请稍候,内容即将加载' },
  ];

  const { data: posts, isLoading } = useQuery({
    queryKey: ['posts'],
    queryFn: fetchPosts,
    placeholderData: placeholderPosts,
  });

  // isLoading为true,同时渲染占位数据,请求完成后自动替换为真实数据
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>
          <h3>{post.title}</h3>
          <p>{post.content}</p>
        </li>
      ))}
    </ul>
  );
}

3. initialData进阶:从其他缓存取初始值

如果需要从另一个Query缓存中获取初始数据,可以用函数形式的initialData:

import { useQuery, useQueryClient } from '@tanstack/react-query';

const fetchUserPosts = async (userId) => {
  const res = await fetch(`/api/users/${userId}/posts`);
  return res.json();
};

function UserPosts({ userId }) {
  const queryClient = useQueryClient();

  const { data: posts } = useQuery({
    queryKey: ['userPosts', userId],
    queryFn: () => fetchUserPosts(userId),
    // 从用户缓存中获取已有的userId,作为初始查询的参数依据
    initialData: () => queryClient.getQueryData(['user'])?.posts || [],
  });

  return (
    <div>
      {posts.length > 0 ? (
        <ul>{posts.map(post => <li key={post.id}>{post.title}</li>)}</ul>
      ) : (
        <p>暂无帖子</p>
      )}
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Solomon Botchway

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:22:44