React Native中表单提交触发React Query获取数据的问题
解决React Query表单提交时refetch不触发或变量丢失问题
问题根源
- QueryKey未关联变量:你的
usePrice查询的queryKey是固定的['price'],导致不同参数的请求共享同一缓存键,React Query可能跳过重复请求或出现缓存混乱。 - 初始调用未传变量:调用
usePrice()时未传入初始变量,fetcher执行时variables为undefined,既会导致初始请求失败,也会让refetch的变量无法正确关联到缓存逻辑。 - 变量类型不匹配:传递给
refetch的formData可能和usePrice定义的Variables类型不匹配,导致参数无法正确传递到API请求。
解决方案
1. 修正use-price-query.ts的QueryKey
让queryKey动态依赖变量,确保不同参数生成唯一缓存键:
export const usePrice = createQuery<Response, Variables, AxiosError>({ // 用函数生成包含变量的queryKey,确保不同参数有独立缓存 queryKey: (variables) => ['price', variables], fetcher: (variables) => { return client.get('/items', { params: { item: variables.item, }, }).then((response) => response.data); }, });
2. 优化组件中的查询调用与表单提交逻辑
方式一:手动控制查询时机(推荐,符合提交触发查询的需求)
初始禁用自动查询,提交时通过refetch传入正确变量:
const schema = z.object({ type: z.string(), // 其他表单字段定义 }); type FormType = z.infer<typeof schema>; // 确保Variables类型与FormType的映射关系,比如Variables中的item对应FormType的type type Variables = { item: string; }; const PriceForm = () => { const { handleSubmit, control } = useForm<FormType>({ resolver: zodResolver(schema), defaultValues: { type: '', // 其他字段默认值 }, }); // 初始禁用自动查询,避免无效请求 const { data, refetch } = usePrice({ enabled: false, }); const onSubmit = (formData: FormType) => { // 将表单数据转换为符合Variables类型的参数 const queryVariables: Variables = { item: formData.type, // 其他需要映射的参数 }; refetch(queryVariables); }; return ( <View className="flex-1 justify-center p-4"> <ControlledSelect control={control} name="type" /> <ControlledInput control={control} name="etc" /> {/* 更多表单字段 */} <Button label="Get Shipping Rates" onPress={handleSubmit(onSubmit)} variant="default" /> </View> ); };
方式二:自动随表单数据更新查询
如果需要表单数据变化时自动触发查询(可选),可以通过enabled控制查询时机:
const PriceForm = () => { const { handleSubmit, control, watch } = useForm<FormType>({ resolver: zodResolver(schema), defaultValues: { type: '' }, }); // 监听所有表单数据 const formData = watch(); // 构造查询变量 const queryVariables: Variables = { item: formData.type }; // 当表单必填项满足时自动触发查询 const { data } = usePrice({ variables: queryVariables, enabled: !!formData.type, // 比如当type不为空时才触发 }); const onSubmit = () => { // 这里可以手动触发refetch确保最新数据,或者直接用已有的data // refetch(); }; return ( // 表单结构同前 ); };
关键注意事项
- 类型匹配:确保传递给
refetch的变量类型与usePrice定义的Variables完全一致,避免参数传递错误。 - 缓存策略:动态
queryKey会为每个不同的参数生成独立缓存,符合GET请求的缓存需求,无需使用Mutation。 - 初始请求控制:通过
enabled: false避免组件挂载时的无效请求,只在表单提交时触发查询。
内容的提问来源于stack exchange,提问作者user1199981
相关产品推荐
相关产品推荐

