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

React Native使用axios实现搜索时如何保证请求与响应顺序一致

问题解决方案

你遇到的是搜索场景典型的请求竞态问题,推荐优先使用AbortController终止过期请求的方案,不仅能解决结果错乱问题,还能减少无效网络消耗,是该场景的最优解法。

方案一:AbortController 终止过期请求(推荐)

核心逻辑:每次发起新的搜索请求前,终止上一次未完成的旧请求,旧请求被终止后不会触发后续的结果更新逻辑。
修改后的代码如下:

function Search (){
    const [results, setResults] = useState([]);
    const [searchText, setSearchText] = useState('');
    // 存储请求的取消控制器
    const abortControllerRef = useRef(null);

    useEffect(() => {
        getSearchResultsDebounce(searchText);
        // 组件卸载时取消待执行的防抖函数和未完成的请求
        return () => {
            getSearchResultsDebounce.cancel();
            abortControllerRef.current?.abort();
        }
    }, [searchText]);

    const getSearchResultsDebounce = useCallback(
        _.debounce(searchText => {
            // 发起新请求前,先取消上一次未完成的请求
            abortControllerRef.current?.abort();
            // 创建新的取消控制器
            const newController = new AbortController();
            abortControllerRef.current = newController;
            getSearchResults(searchText, newController.signal);
        }, 1000),
        []
    );

    function getSearchResults(searchText, signal) {
        const urlWithParams = getUrlWithParams(url, searchText);
        axios.get(urlWithParams, { 
            headers: config.headers,
            // 传入signal关联请求和取消控制器
            signal: signal
        })
        .then(response => {
            if (response.status === 200 && response.data) {
                setResults(response.data);
            } else{
                //Handle error
            }
        })
        .catch(error => {
            // 忽略请求被取消的报错,不要当成异常处理
            if (axios.isCancel(error)) return;
            // 其他错误正常处理
            //Handle error
        });
    }

    return (
     <View>
        <SearchComponent onTextChange={setSearchText}/>
        <SearchResults results={results}/>
     </View>
    )
}

方案二:搜索词比对忽略过期响应(无取消请求需求时可选)

如果你的业务场景需要保留所有请求的响应结果,不需要取消请求,可以用比对当前返回结果对应搜索词和最新搜索词的方式,只更新最新搜索词对应的结果:
只需要新增搜索词ref并修改getSearchResults的逻辑即可:

function Search (){
    const [results, setResults] = useState([]);
    const [searchText, setSearchText] = useState('');
    // 存储最新的搜索词
    const latestSearchTextRef = useRef('');

    useEffect(() => {
        latestSearchTextRef.current = searchText;
        getSearchResultsDebounce(searchText);
        return () => {
            getSearchResultsDebounce.cancel();
        }
    }, [searchText]);

    const getSearchResultsDebounce = useCallback(
        _.debounce(searchText => {
            getSearchResults(searchText)
        }, 1000),
        []
    );

    function getSearchResults(searchText) {
        const urlWithParams = getUrlWithParams(url, searchText);
        axios.get(urlWithParams, { headers: config.headers })
        .then(response => {
            if (response.status === 200 && response.data) {
                // 只有返回结果对应的搜索词和当前最新搜索词一致时才更新状态
                if(searchText === latestSearchTextRef.current) {
                    setResults(response.data);
                }
            } else{
                //Handle error
            }
        })
        .catch(error => {
            //Handle error
        });
    }

    return (
     <View>
        <SearchComponent onTextChange={setSearchText}/>
        <SearchResults results={results}/>
     </View>
    )
}

两种方案都能完全解决请求返回顺序错乱导致的结果错误问题,优先选择方案一即可。

内容的提问来源于stack exchange,提问作者chathup1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:12:03