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

React-Redux搜索功能Action无限调用问题求助

问题:React-Redux搜索功能触发Action无限调用

我在使用React-Redux实现搜索功能时,每次搜索数据都会导致Redux无限调用Action。虽然能返回正确结果,但会触发无限次调用,甚至出现undefined的情况。请问该如何解决这个问题?


Action

export const SEARCH_PRO = (query) =>{
    return {
        type: SEARCH_PROS,
        query,
       
    }
}

Reducer

export const productData = (state = { searchDatas: [] }, action) => {
    switch (action.type) {
            case SEARCH_PROS:
                console.warn("PRODUCT_LIST condition ", action.searchProds)
                return {searchDatas:[action.searchProds]}
        default:
            return state
    }
}

Saga

function* searchProducts(data) {
    let result = yield fetch(`products/searchpro?search=${data.query}`);
    result = yield result.json();
    console.warn("products action is called", result)
    console.warn("products action is ", data.query)
    yield put({type: SEARCH_PROS, searchProds:result.products.data})
}

export function* productSaga() {
    yield takeEvery(SEARCH_PROS, searchProducts)
}

搜索组件

<input type="search" className="form-control" name="search" placeholder="Search your Products" onChange={(event) => dispatch(SEARCH_PRO(event.target.value))} />

问题原因与解决方法

核心原因

你的代码里同一个SEARCH_PROS类型被同时用作「触发搜索请求的Action」和「接收搜索结果的Action」:Saga监听SEARCH_PROS发起请求,请求完成后又dispatch了同类型的Action,导致Saga再次监听、再次发起请求,形成无限循环。

具体修复步骤

  1. 拆分Action类型
    新增一个专门用于接收搜索结果的Action类型,让原SEARCH_PROS只负责触发请求:

    // Action定义
    export const SEARCH_PRO = (query) => ({
        type: 'SEARCH_PROS',
        query
    })
    
    export const SEARCH_PROS_SUCCESS = (searchProds) => ({
        type: 'SEARCH_PROS_SUCCESS',
        searchProds
    })
    
  2. 修改Reducer逻辑
    让Reducer只响应SEARCH_PROS_SUCCESS来更新状态,同时保留原状态的其他字段:

    export const productData = (state = { searchDatas: [] }, action) => {
        switch (action.type) {
            case 'SEARCH_PROS_SUCCESS':
                console.warn("PRODUCT_LIST condition ", action.searchProds)
                return { ...state, searchDatas: action.searchProds }
            default:
                return state
        }
    }
    

    注:原代码里[action.searchProds]会把结果额外包成数组,可能导致数据结构错误,这里直接赋值action.searchProds即可。

  3. 调整Saga逻辑
    Saga监听SEARCH_PROS,请求完成后dispatchSEARCH_PROS_SUCCESS而非原类型,同时添加异常捕获避免请求崩溃:

    function* searchProducts(data) {
        try {
            let result = yield fetch(`products/searchpro?search=${data.query}`);
            result = yield result.json();
            console.warn("products action is called", result)
            console.warn("products action is ", data.query)
            yield put({type: 'SEARCH_PROS_SUCCESS', searchProds: result.products.data})
        } catch (error) {
            console.error('搜索请求失败:', error)
        }
    }
    
    export function* productSaga() {
        yield takeEvery('SEARCH_PROS', searchProducts)
    }
    
  4. 优化搜索组件(可选)
    给输入框添加防抖处理,避免每输入一个字符就发起请求,减少无效请求:

    import { useCallback, useState } from 'react'
    
    const debounce = (func, delay) => {
        let timeoutId;
        return (...args) => {
            clearTimeout(timeoutId);
            timeoutId = setTimeout(() => func.apply(this, args), delay);
        };
    }
    
    const SearchComponent = () => {
        const dispatch = useDispatch();
        const debouncedSearch = useCallback(debounce((query) => {
            dispatch(SEARCH_PRO(query))
        }, 300), [dispatch])
    
        return (
            <input 
                type="search" 
                className="form-control" 
                name="search" 
                placeholder="搜索你的产品" 
                onChange={(event) => debouncedSearch(event.target.value)} 
            />
        )
    }
    

内容的提问来源于stack exchange,提问作者Md. Ashikur Rahman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:50:31