You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 18:54:52