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
相关产品推荐
相关产品推荐

