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

Redux-Saga引发网站无限重渲染问题求助

Redux-Saga 导致无限重渲染的解决方法

问题根源

你的代码形成了无限循环:

  • Saga 通过 takeEvery(GET_EMPLOYEE_LIST, workEmployeeList) 监听 GET_EMPLOYEE_LIST 类型的 action
  • 在请求完成后,workEmployeeList 又通过 yield put({type: GET_EMPLOYEE_LIST, ...}) 再次触发同一个 action
  • 这会导致 Saga 反复执行请求逻辑,不断触发状态更新,最终引发组件无限重渲染

解决步骤

核心是拆分 action 类型,将触发请求和更新状态的操作分离:

  1. 新增区分用途的 action 类型
    在 EmployeeActions.js 里定义两个不同的 action 类型:
export const GET_EMPLOYEE_LIST_REQUEST = 'GET_EMPLOYEE_LIST_REQUEST'; // 触发请求
export const GET_EMPLOYEE_LIST_SUCCESS = 'GET_EMPLOYEE_LIST_SUCCESS'; // 请求成功后更新状态
// 可选:新增失败类型用于错误处理
// export const GET_EMPLOYEE_LIST_FAILURE = 'GET_EMPLOYEE_LIST_FAILURE';
  1. 修改 Saga 逻辑
    让 Saga 监听请求触发的 action,成功后派发状态更新的 action:
import { call, put, takeEvery } from 'redux-saga/effects'
import axios from 'axios'
import { GET_EMPLOYEE_LIST_REQUEST, GET_EMPLOYEE_LIST_SUCCESS } from './actions/EmployeeActions'
import ConstantList from '../../app/appConfig'

const API_PATH = ConstantList.API_ENPOINT + "/employees"

export function* getEmployeeList() {
    // 改为监听请求触发类型的 action
    yield takeEvery(GET_EMPLOYEE_LIST_REQUEST, workEmployeeList)
}

export function* workEmployeeList() {
    console.trace("hello");
    try {
        const url = API_PATH + '/search'
        const response = yield call(axios.post, url, {})

        // 派发状态更新类型的 action,不再复用请求触发类型
        yield put({
            type: GET_EMPLOYEE_LIST_SUCCESS,
            payload: response.data.data
        })

    } catch (error) {
        console.log("Request failed!")
        // 可选:派发失败类型 action 处理错误状态
        // yield put({type: GET_EMPLOYEE_LIST_FAILURE, error: error})
    }
}
  1. 修改 Reducer 处理状态更新
    在 EmployeeReducer.js 中处理成功类型的 action 来更新状态:
import { GET_EMPLOYEE_LIST_SUCCESS } from '../actions/EmployeeActions'

const initialState = {
    employeeList: []
};

export default function EmployeeReducer(state = initialState, action) {
    switch(action.type) {
        case GET_EMPLOYEE_LIST_SUCCESS:
            return {
                ...state,
                employeeList: action.payload
            };
        // 可选:处理失败状态
        // case GET_EMPLOYEE_LIST_FAILURE:
        //     return {...state, error: action.error};
        default:
            return state;
    }
}
  1. 组件中触发请求
    在需要获取员工列表的组件里,派发请求触发类型的 action:
import { useDispatch } from 'react-redux'
import { useEffect } from 'react'
import { GET_EMPLOYEE_LIST_REQUEST } from './path/to/EmployeeActions'

function EmployeeList() {
    const dispatch = useDispatch();

    useEffect(() => {
        // 触发请求
        dispatch({type: GET_EMPLOYEE_LIST_REQUEST});
    }, [dispatch]);

    // ...其他渲染逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:40:32