如何阻止Redux的useFetchLocationsQuery Hook在查询为空时请求服务器
解决Redux Toolkit Query空查询时阻止请求的问题
你可以通过Redux Toolkit Query(RTK Query)提供的skip参数直接控制请求是否发起,同时也可以在API定义层做一层防护,双重避免无效请求。
核心方案:使用skip参数
直接在调用useFetchLocationsQuery时,判断查询字符串是否为空,为空则设置skip: true,RTK Query就会跳过这次请求:
// 修改组件中的Hook调用 const { data } = useFetchLocationsQuery(query, { // 当query为空(含全空格)时跳过请求 skip: query.trim() === '' });
这样不管是应用初始化(query初始为空)还是用户清空输入框,都不会触发服务器请求。
可选:API定义层额外防护
为了更严谨,你可以在createApi的fetchLocations endpoint里先判断参数是否为空,提前拦截无效请求:
// 示例:store中的API定义 import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; export const locationsApi = createApi({ reducerPath: 'locationsApi', baseQuery: fetchBaseQuery({ baseUrl: '/api/' }), endpoints: (builder) => ({ fetchLocations: builder.query({ query: (queryStr) => { // 空查询直接返回空数据的mock响应,不发起真实请求 if (!queryStr.trim()) { return { url: '', method: 'GET', responseHandler: () => Promise.resolve([]) }; } // 正常请求逻辑 return { url: 'locations', params: { q: queryStr } }; }, }), }), }); export const { useFetchLocationsQuery } = locationsApi;
组件代码优化建议
你的防抖逻辑可以简化,减少不必要的函数嵌套:
import { Autocomplete, Button, Grid, TextField } from '@mui/material'; import { useFetchLocationsQuery } from '../store'; import { useMemo, useState } from 'react'; import debounce from 'lodash.debounce'; export function AddLocationComponent() { const [query, setQuery] = useState(''); // 添加skip参数控制请求 const { data } = useFetchLocationsQuery(query, { skip: query.trim() === '' }); const options = (data || []).map(p => p.name); // 直接防抖处理setQuery,减少中间函数 const debouncedSetQuery = useMemo(() => debounce((value) => setQuery(value), 2000), []); const renderInput = params => { return <TextField {...params} onChange={(e) => debouncedSetQuery(e.target.value)} label="With categories" /> } return ( <div> <Grid container> <Grid item xs={10}> <Autocomplete options={options} renderInput={renderInput} onInputChange={(e, value) => debouncedSetQuery(value)} /> </Grid> </Grid> </div> ); }
内容的提问来源于stack exchange,提问作者Vojtech
相关产品推荐
相关产品推荐

