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

React处理双查询加载状态:优化方案及react-query可行性咨询

传统React优化实现

不需要额外依赖,核心是把两个请求的状态拆分并统一管理,让每个请求的加载状态独立更新,数据到了就渲染:

  • 用单个状态对象替代零散的loading变量,让状态管理更集中
  • 每个请求完成后单独更新对应状态,无需等待全部请求结束
import { useState, useEffect } from 'react';

function Home() {
  const [posts, setPosts] = useState([]);
  const [songs, setSongs] = useState([]);
  // 用对象统一管理两类数据的加载状态
  const [loadingStates, setLoadingStates] = useState({
    posts: true,
    songs: true
  });

  useEffect(() => {
    // 加载posts
    fetch('/api/posts')
      .then(res => res.json())
      .then(data => {
        setPosts(data);
        setLoadingStates(prev => ({ ...prev, posts: false }));
      })
      .catch(err => {
        console.error('文章加载失败:', err);
        setLoadingStates(prev => ({ ...prev, posts: false }));
      });

    // 加载songs
    fetch('/api/songs')
      .then(res => res.json())
      .then(data => {
        setSongs(data);
        setLoadingStates(prev => ({ ...prev, songs: false }));
      })
      .catch(err => {
        console.error('歌曲加载失败:', err);
        setLoadingStates(prev => ({ ...prev, songs: false }));
      });
  }, []);

  return (
    <div className="home">
      <section>
        <h2>文章列表</h2>
        {loadingStates.posts ? (
          <div className="loading">加载文章中...</div>
        ) : (
          <ul>
            {posts.map(post => (
              <li key={post.id}>{post.title}</li>
            ))}
          </ul>
        )}
      </section>

      <section>
        <h2>歌曲列表</h2>
        {loadingStates.songs ? (
          <div className="loading">加载歌曲中...</div>
        ) : (
          <ul>
            {songs.map(song => (
              <li key={song.id}>{song.name}</li>
            ))}
          </ul>
        )}
      </section>
    </div>
  );
}

这种方式把零散的loading变量整合,逻辑清晰,每个请求的状态更新独立,完全满足“数据到了就渲染”的需求。

React Query 简化实现

React Query(现名TanStack Query)专门解决数据获取的状态管理问题,能彻底省去手动维护data、loading、error状态的代码,直接用钩子封装每个请求的生命周期:

先安装依赖:

npm install @tanstack/react-query

然后实现页面:

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

// 创建全局QueryClient实例
const queryClient = new QueryClient();

function Home() {
  // 加载posts,自动管理加载、数据、错误状态
  const { data: posts, isLoading: loadingPosts, error: postsError } = useQuery({
    queryKey: ['posts'], // 唯一标识请求,用于缓存和更新
    queryFn: () => fetch('/api/posts').then(res => res.json())
  });

  // 加载songs,同理
  const { data: songs, isLoading: loadingSongs, error: songsError } = useQuery({
    queryKey: ['songs'],
    queryFn: () => fetch('/api/songs').then(res => res.json())
  });

  return (
    <div className="home">
      <section>
        <h2>文章列表</h2>
        {loadingPosts && <div className="loading">加载文章中...</div>}
        {postsError && <div className="error">文章加载失败: {postsError.message}</div>}
        {posts && !loadingPosts && (
          <ul>
            {posts.map(post => (
              <li key={post.id}>{post.title}</li>
            ))}
          </ul>
        )}
      </section>

      <section>
        <h2>歌曲列表</h2>
        {loadingSongs && <div className="loading">加载歌曲中...</div>}
        {songsError && <div className="error">歌曲加载失败: {songsError.message}</div>}
        {songs && !loadingSongs && (
          <ul>
            {songs.map(song => (
              <li key={song.id}>{song.name}</li>
            ))}
          </ul>
        )}
      </section>
    </div>
  );
}

// 在根组件中包裹全局Provider
function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Home />
    </QueryClientProvider>
  );
}

React Query不仅简化了状态管理,还自带缓存、重试、背景刷新等实用功能,代码更简洁易维护,天然支持独立渲染每个请求的结果。

内容的提问来源于stack exchange,提问作者Coding Ninja123211

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:09:55