React Query中使用axios.request(options)时变量参数失效问题求助
问题原因分析
你的问题核心在于状态更新的异步性和查询函数未使用最新参数:
- 调用
setTvSearchQuery(data.tvSearch)后,React状态更新是异步的,立刻执行refetch()时,tvSearchQuery还未完成更新,导致请求参数仍是旧值。 options对象随组件渲染创建,但fetchTvData直接引用外部的options,当搜索关键词更新后,查询函数可能无法捕获最新的请求配置。
修复方案
方案1:让查询函数接收明确参数
将搜索关键词作为参数传入查询函数,确保每次请求都使用最新值:
import { useQuery } from "react-query"; import axios from "axios"; import { Stack, TextField, Button } from "@mui/material"; import { useForm } from "react-hook-form"; import { useState } from "react"; interface FormValues { tvSearch: string; } interface Tv { id: number; } interface ShowData { data: Tv[]; } function ShowBox() { const [tvSearchQuery, setTvSearchQuery] = useState(""); const form = useForm<FormValues>({ defaultValues: { tvSearch: "", }, }); const { register, handleSubmit, formState } = form; const { errors } = formState; // 让fetchTvData接收搜索关键词参数,内部创建请求配置 function fetchTvData(searchQuery: string): Promise<ShowData> { return axios.request({ method: "GET", url: "https://api.themoviedb.org/3/search/tv", params: { query: searchQuery, include_adult: "false", language: "en-US", page: "1", }, headers: { accept: "application/json", Authorization: "Bearer key1234", }, }); } function onSubmit(data: FormValues) { setTvSearchQuery(data.tvSearch); // 直接传入表单的最新值触发查询 refetch(data.tvSearch); } function onSuccess(data: ShowData) { console.log("success", data); } function onError(error: Error) { console.log("ERROR", error); } const { data, refetch } = useQuery({ queryKey: ["tvSearchQuery", tvSearchQuery], // 使用queryKey中的参数作为查询函数输入 queryFn: () => fetchTvData(tvSearchQuery), refetchOnWindowFocus: false, enabled: false, onSuccess, onError, }); console.log(data?.data); return ( <form onSubmit={handleSubmit(onSubmit)} noValidate> <Stack spacing={2}> <TextField label="输入剧集或电影名称" type="text" {...register("tvSearch")} error={!!errors.tvSearch} helperText={errors.tvSearch?.message} /> <Button type="submit" variant="contained"> 搜索 </Button> </Stack> </form> ); }
方案2:通过refetch传递参数
如果不想修改查询函数结构,可借助refetch的参数传递能力:
// ... 其他代码不变 function onSubmit(data: FormValues) { // 直接使用表单提交的最新值,不依赖异步状态更新 refetch(data.tvSearch); } const { data, refetch } = useQuery({ queryKey: ["tvSearchQuery", tvSearchQuery], // 从queryKey或refetch参数中获取最新搜索关键词 queryFn: ({ queryKey }) => { const [_, searchQuery] = queryKey; return axios.request({ ...options, params: { ...options.params, query: searchQuery }, }); }, refetchOnWindowFocus: false, enabled: false, onSuccess, onError, });
关键要点总结
- 避免依赖异步状态更新:表单提交时直接使用表单数据,不要等待
setState完成。 - 保持查询键与请求参数一致:React Query会根据
queryKey的变化触发重新查询,确保查询函数使用的参数和queryKey同步。 - 不要让查询函数依赖外部可变对象:尽量在查询函数内部创建请求配置,或传递明确参数,避免引用外部可能过时的对象。
内容的提问来源于stack exchange,提问作者Brenden Baio
相关产品推荐
相关产品推荐

