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

组件传递给worker Saga的action.payload处理中变为undefined求助

问题:Action Payload传递到Worker Saga后变为Undefined

我遇到一个问题:从组件把action.payload传递到Worker Saga后,在处理Action的过程中它变成了undefined。控制台打印显示action.payload.queries和action.payload.chosenQueryId均为undefined。以下是我的代码片段:

组件中的Action触发代码

const showQueryOnMapHandler = (event) => {
  const chosenQueryId = +event.currentTarget.id;
  dispatch(mapActions.setCoordinates({ chosenQueryId, queries }));
};

Saga代码

const getQueryCoordinates = (action) => {
  console.log(action.payload.queries);
  console.log(action.payload.chosenQueryId);

  const queryIndex = action.payload.queries.findIndex(
    (element) => element.queryId === action.payload.chosenQueryId
  );

  const coordinatesFromTo = {
    newFromLat: action.payload.queries[queryIndex].coordinatesFrom.lat,
    newFromLng: action.payload.queries[queryIndex].coordinatesFrom.lng,
    newToLat: action.payload.queries[queryIndex].coordinatesTo.lat,
    newToLng: action.payload.queries[queryIndex].coordinatesTo.lng,
  };
  return coordinatesFromTo;
};

function* workerQueryClickSaga(action) {
  yield put(queriesActions.choseQuery(action.payload.chosenQueryId));
  yield put(mapActions.setCoordinates(getQueryCoordinates(action)));
  yield put(mapActions.setBounds());
}

function* watchQueryClickSaga() {
  yield takeEvery("map/setCoordinates", workerQueryClickSaga);
}

function* rootSaga() {
  yield fork(watchQueryClickSaga);
}

export default rootSaga;

Redux Store配置

import { configureStore } from "@reduxjs/toolkit";
import createSagaMiddleware from "redux-saga";
import mapSlice from "./reducers/map-slice";
import queriesSlice from "./reducers/queries-slice";
import rootSaga from "./sagas";

const saga = createSagaMiddleware();

const store = configureStore({
  reducer: { queries: queriesSlice.reducer, map: mapSlice.reducer },
  middleware: [saga],
});

saga.run(rootSaga);

export default store;

Map Slice代码

import { createSlice } from "@reduxjs/toolkit";

const mapSlice = createSlice({
  name: "map",
  initialState: {
    fromLat: null,
    fromLng: null,
    toLat: null,
    toLng: null,
    bounds: null,
    fetchedPolyline: [],
  },
  reducers: {
    setCoordinates(state, action) {
      state.fromLat = action.payload.fromLat;
      state.fromLng = action.payload.fromLng;
      state.toLat = action.payload.toLat;
      state.toLng = action.payload.toLng;
    },
    setBounds(state) {
      state.bounds = [
        [state.fromLat, state.fromLng],
        [state.toLat, state.toLng],
      ];
    },
  },
});

export const mapActions = mapSlice.actions;

export default mapSlice;

Queries Slice代码(存在笔误)

import { createSlice } from "@reduxjs/toolkit";

const mapSlice = createSlice({
  name: "map",
  initialState: {
    fromLat: null,
    fromLng: null,
    toLat: null,
    toLng: null,
    bounds: null,
    fetchedPolyline: [],
  },
  reducers: {
    setCoordinates(state, action) {
      state.fromLat = action.payload.fromLat;
      state.fromLng = action.payload.fromLng;
      state.toLat = action.payload.toLat;
      state.toLng = action.payload.toLng;
    },
    setBounds(state) {
      state.bounds = [
        [state.fromLat, state.fromLng],
        [state.toLat, state.toLng],
      ];
    },
  },
});

export const mapActions = mapSlice.actions;

export default mapSlice;

已尝试的方法

我试过把getQueryCoordinates函数的逻辑直接放到workerQueryClickSaga里,但问题依然存在。


问题原因与修复方案

核心问题

  1. 循环触发Action导致Payload丢失:你的Saga监听了map/setCoordinates这个Action,但在workerQueryClickSaga里又再次调用put(mapActions.setCoordinates(...)),形成循环触发。第二次触发时,传递的payload是getQueryCoordinates(action)返回的对象(只有newFromLat等坐标字段),没有queries和chosenQueryId,所以后续Saga处理时action.payload自然找不到这些属性,打印为undefined。
  2. Queries Slice笔误:你提供的Queries Slice代码完全复制了Map Slice的内容,这会导致Redux状态管理混乱,也无法正常使用queriesActions.choseQuery。

修复步骤

  1. 新增专用触发Action:在Queries Slice里创建专门用于触发查询点击的Action,而非复用Map的Action:
// queries-slice.js 修正后代码
import { createSlice } from "@reduxjs/toolkit";

const queriesSlice = createSlice({
  name: "queries",
  initialState: {
    chosenQueryId: null,
    queryList: [] // 根据实际需求定义状态
  },
  reducers: {
    choseQuery(state, action) {
      state.chosenQueryId = action.payload;
    },
    // 新增专门触发Saga的Action
    queryClicked(state, action) {
      // 此Action仅作为Saga触发信号,无需修改状态
    }
  },
});

export const queriesActions = queriesSlice.actions;
export default queriesSlice;
  1. 组件中触发正确的Action:
const showQueryOnMapHandler = (event) => {
  const chosenQueryId = +event.currentTarget.id;
  // 触发新增的queryClicked,传递所需参数
  dispatch(queriesActions.queryClicked({ chosenQueryId, queries }));
};
  1. 修改Saga监听与逻辑:
function* workerQueryClickSaga(action) {
  const { chosenQueryId, queries } = action.payload;
  yield put(queriesActions.choseQuery(chosenQueryId));
  
  // 直接从payload取数据,避免依赖循环触发的Action
  const queryIndex = queries.findIndex(element => element.queryId === chosenQueryId);
  const coordinates = {
    fromLat: queries[queryIndex].coordinatesFrom.lat,
    fromLng: queries[queryIndex].coordinatesFrom.lng,
    toLat: queries[queryIndex].coordinatesTo.lat,
    toLng: queries[queryIndex].coordinatesTo.lng,
  };
  yield put(mapActions.setCoordinates(coordinates));
  yield put(mapActions.setBounds());
}

function* watchQueryClickSaga() {
  // 监听新增的queries/queryClicked Action
  yield takeEvery("queries/queryClicked", workerQueryClickSaga);
}

这样就能彻底避免循环触发的问题,保证Saga每次都能拿到完整且正确的payload。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:35:49