使用React Query时数据仅在标签页切换后才显示如何解决
问题原因
useQuery的查询key写死为"employees",没有将搜索参数name作为依赖项加入key中,React Query默认只有key变化时才会重新触发查询- React Query默认开启
refetchOnWindowFocus配置,切走标签页再切回时会触发窗口聚焦事件,才会重新执行查询,这就是你只有切页才会拿到数据的直接原因 setName是异步更新状态的操作,你在getValue函数中调用setName(e)后立即传name调用getEmployeesList,拿到的永远是更新前的旧name值,且你手动调用接口返回的结果没有同步给useQuery维护的data,属于无效调用
修复方案
- 将
name加入useQuery的查询key数组,name变化时自动触发重新查询 - 删掉
getValue中的手动getEmployeesList调用,所有接口请求完全交给useQuery管理 - 可选:如果不需要窗口聚焦时自动重查,可以给
useQuery加配置refetchOnWindowFocus: false
修改后的核心代码
import React, { ChangeEvent, useState, ReactElement } from "react"; import { useQuery, UseQueryResult } from "react-query"; import axios from "axios"; import { API_URL } from "../../settings"; import SearchBar from "../../components/search-bar"; const Employees = (): ReactElement => { type Employee = Record<string, any>; const [name, setName] = useState(""); function getValue(eventData: ChangeEvent<HTMLInputElement>) { const e = eventData.target.value; setName(e); } async function getEmployeesList(name: string) { const { data } = await axios.get( API_URL + "employees?q[firstname_or_lastname_cont]=" + name ); return data; } const { data, error, isError, isLoading, }: UseQueryResult<Employee[], Error> = useQuery(["employees", name], () => getEmployeesList(name) // 不需要窗口聚焦自动重查可放开下面的配置 // , { refetchOnWindowFocus: false } ); if (isLoading) { return <div>Loading...</div>; } if (isError) { return ( <div> Error! {error?.message} </div> ); } return ( <div className="findEmployees"> <SearchBar placeholder="" value={name} onValueChange={getValue} /> <div className="listContainer"> <h1>Employees</h1> {data?.map((employee) => ( <li key={employee.id}> {employee.firstname} {employee.lastname} <p>{employee.role}</p> </li> ))} </div> </div> ); }; export default Employees;
额外优化建议
如果搜索时不需要输入一个字符就查询一次,可以加防抖处理,比如用useDebounce封装name,将防抖后的值传入useQuery的key,减少不必要的接口请求。
内容的提问来源于stack exchange,提问作者Red_system
相关产品推荐
相关产品推荐

