如何减少键盘输入查询及页面刷新时的服务请求次数?
解决搜索输入频繁请求与页面刷新额外请求的优化方案
一、用防抖(Debounce)限制输入时的请求频率
每次输入字符就触发请求,是因为useEffect监听stateRegion.query的变化,只要query改变就调用getDataRegion。防抖可以让请求在用户停止输入一段时间后才发送,避免短时间内频繁触发接口请求。
- 先实现一个防抖函数:
const debounce = (func, delay) => { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; };
- 对
getDataRegion做防抖处理,并在useEffect中使用防抖后的函数:
修改你的组件代码如下:
import { getUrLOptions } from "../../../api/config"; import { useState, useEffect, useCallback } from "react"; const YourComponent = (props) => { const [stateRegion, setStateRegion] = useState({ data: { suggestions: [] }, query: '', // 初始设为空字符串,避免页面加载时触发无效请求 value: props.data["UF_REGION"+prefix] || "", valueKLADR: props.data["UF_REGION_KLADR"+prefix] || "", abortController: null // 用于取消未完成的请求 }); const getDataRegion = () => { const trimmedQuery = stateRegion.query.trim(); if (trimmedQuery.length === 0) { setStateRegion(prev => ({...prev, data: {suggestions: []}})); return; } // 取消之前未完成的请求,避免旧结果覆盖新结果 if (stateRegion.abortController) { stateRegion.abortController.abort(); } const newAbortController = new AbortController(); setStateRegion(prev => ({...prev, abortController: newAbortController})); const conf = getUrLOptions(trimmedQuery, {}, "region"); fetch(conf.url, {...conf.options, signal: newAbortController.signal}) .then((response) => response.json()) .then((result) => { setStateRegion((prevState) => ({ ...prevState, data: result, })); }) .catch((error) => { // 忽略请求取消的错误 if (error.name !== 'AbortError') { console.log('error', error); } }); }; // 用useCallback包裹防抖函数,避免组件每次渲染重新创建函数 const debouncedGetData = useCallback(debounce(getDataRegion, 300), []); useEffect(() => { debouncedGetData(); }, [stateRegion.query, debouncedGetData]); return ( // 你的组件JSX内容 ); }; // 防抖函数 const debounce = (func, delay) => { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; }; export default YourComponent;
二、避免页面刷新时的额外请求
原来的初始query设为' '(空格),页面加载时会触发useEffect发送无效请求。现在把初始query改为空字符串,并在getDataRegion里判断query去除空格后是否有有效内容,这样页面刷新时不会触发不必要的请求。
内容的提问来源于stack exchange,提问作者Alisa
相关产品推荐
相关产品推荐

