解决React Query初始加载误显示「无数据」的问题
解决React Query初始加载时短暂显示空状态的问题
问题根源在于初始加载阶段请求还未完成,data处于null或undefined状态,但你的条件判断直接触发了「未找到记录」的分支。React Query提供的isLoading状态可以帮我们区分「加载中」和「加载完成后无数据」这两种场景,调整逻辑即可解决:
具体修改方案
- 先判断
isLoading:请求进行中时,显示加载提示(或保持空白) - 请求完成后,再判断
data是否为空数组 - 额外处理
isError状态,捕获请求失败的情况
修改后的完整代码
import React, { useState } from "react"; import Card from "../../Components/Giveaway Card/Card"; import PopUp from "../../Components/GamesDetailsPopUp/PopUp"; import SortByDropDown from '../../Components/SortByDropdown/SortByDropDown'; import { fetchSorteoData } from '../../util/Queries'; import { useQuery } from 'react-query'; export default function Dashboard() { const [PopUpModal, setPopUpModal] = useState(false); const [selectedSorteo, setSelectedSorteo] = useState(null) const [paidChecked, setPaidChecked] = useState(false); const [freeChecked, setFreeChecked] = useState(false); const { data, isLoading, isError } = useQuery({ queryKey: ['sorteoData', selectedSorteo, freeChecked, paidChecked], queryFn: () => fetchSorteoData(selectedSorteo, freeChecked, paidChecked) }) const handlePaidChange = () => { setPaidChecked((prevChecked) => !prevChecked); setFreeChecked(false); }; const handleFreeChange = () => { setFreeChecked((prevChecked) => !prevChecked); setPaidChecked(false); }; if (isLoading) { // 加载中可以显示加载动画或文字,也可以返回null保持空白 return <div className='text-5xl text-white font-bold'>加载中...</div>; } if (isError) { return <div className='text-5xl text-white font-bold'>数据加载失败,请稍后重试</div>; } return ( <> <div className="text-white flex text-md font-bold tracking-tight justify-end p-5"> <div className="flex items-center me-4 bg-purple-600 p-2 rounded-lg hover:bg-purple-800 focus:ring-4 focus:outline-none focus:ring-purple-300"> <input type="checkbox" checked={paidChecked} onChange={handlePaidChange} className="w-5 h-5 cursor-pointer text-purple-600 bg-purple-400 border-purple-300 rounded focus:ring-purple-500 focus:ring-2 " /> <label className="ms-2 text-md font-medium">Paid</label> </div> <div className="flex items-center me-4 bg-purple-600 p-2 rounded-lg hover:bg-purple-800 focus:ring-4 focus:outline-none focus:ring-purple-300"> <input type="checkbox" checked={freeChecked} onChange={handleFreeChange} className="w-5 h-5 cursor-pointer text-purple-600 bg-purple-400 border-purple-300 rounded focus:ring-purple-500 focus:ring-2 " /> <label className="ms-2 text-md font-medium">Free</label> </div> <SortByDropDown setSelectedSorteo={setSelectedSorteo} /> </div> {data && data.length > 0 ? ( <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6 justify-items-center gap-5"> {data.map((item, ind) => ( <div key={ind}> <Card item={item} closeModal={() => setPopUpModal(true)} /> <PopUp closeModal={() => setPopUpModal(false)} PopUpModal={PopUpModal} /> </div> ))} </div> ) : ( <div className='text-5xl text-white font-bold'>未找到记录</div> )} </> ); }
关键逻辑说明
- 加载状态拦截:通过
if (isLoading)提前返回加载中的UI,避免请求未完成时进入空状态判断 - 错误状态处理:新增
isError判断,给用户明确的错误提示 - 空状态判断延后:只有当请求完成(
isLoading为false)且data为空数组时,才显示「未找到记录」
内容的提问来源于stack exchange,提问作者saimarshadd
相关产品推荐
相关产品推荐

