如何让RTK Query在用户完成表单后再发起API请求
解决RTK Query自动触发API请求的问题
当前代码中,useAllDataQuery会在formData变化时自动发起API请求,要实现仅在表单提交时触发请求,可以通过RTK Query的useLazyQuery(对应你的useLazyAllDataQuery)手动控制请求时机,具体修改如下:
修改步骤
- 替换
useAllDataQuery为useLazyAllDataQuery:该钩子返回一个触发函数(用于手动发起请求)和查询状态/结果。 - 为表单添加
onSubmit事件:阻止默认表单提交行为,在事件中调用触发函数传入当前表单数据。 - 调整状态监听:监听查询返回的
data,更新Redux状态。 - 修正加载状态变量:按钮上的加载状态使用查询返回的
isFetching。
修改后的完整代码
import { useEffect, useState } from 'react'; import 'flatpickr/dist/themes/dark.css'; import 'nouislider/distribute/nouislider.css'; import { useDispatch } from 'react-redux'; import { setPageTitle } from '../../store/themeConfigSlice'; import { setYearCountrySelection } from '../../store/counterSlice'; // 替换为useLazyAllDataQuery import { useLazyAllDataQuery } from '@/store/features/mainApiSlice'; const YearCountrySelect = () => { const dispatch = useDispatch(); const [formData, setFormData] = useState({ year: 2023, country: 'SPA', }); // 获取触发函数和查询结果 const [triggerAllDataQuery, { data, isFetching }] = useLazyAllDataQuery(); useEffect(() => { if (data) { dispatch(setYearCountrySelection(data)); } }, [data, dispatch]); // 表单提交处理逻辑 const handleSubmit = (e) => { e.preventDefault(); // 手动触发API请求 triggerAllDataQuery({ year: formData.year, country: formData.country }); }; return ( // 绑定表单提交事件 <form className="panel" onSubmit={handleSubmit}> <div className="mb-2 flex items-center justify-between"></div> <div> <select onChange={(e) => setFormData({ ...formData, year: e.target.value })} className="form-select mb-3 text-white-dark" value={formData.year} // 绑定value确保表单值与state同步 > {Array.from({ length: 11 }, (_, i) => 2023 - i).map((item) => ( <option key={item} value={item}> {item} </option> ))} </select> </div> <div> <select onChange={(e) => setFormData({ ...formData, country: e.target.value })} className="form-select mb-3 text-white-dark" value={formData.country} // 绑定value确保表单值与state同步 > <option value={'SPA'}>Spain</option> <option value={'FRA'}>France</option> <option value={'ITA'}>Italy</option> <option value={'GER'}>Germany</option> <option value={'NED'}>Holland</option> <option value={'BEL'}>Belgium</option> </select> </div> <div className="mt-1 flex justify-end"> <button type="submit" className="btn btn-outline-primary mr-1" disabled={isFetching}> {isFetching ? ( <div className="px-2"> <span className="m-auto inline-block h-5 w-5 animate-spin rounded-full border-2 border-primary border-l-transparent align-middle"></span> </div> ) : ( 'Select' )} </button> </div> </form> ); }; export default YearCountrySelect;
额外优化点
- 给
select添加value属性绑定formData对应字段,确保表单控件值与state完全同步,避免出现数据不一致的情况。 - 给提交按钮添加
disabled={isFetching}属性,防止用户在请求过程中重复提交。
内容的提问来源于stack exchange,提问作者Agustin Gonzalez Ribas
相关产品推荐
相关产品推荐

