React-Redux-Saga动作有效载荷在reducer中未定义



我正在尝试创建一个基本的计数器应用程序。然而,在我的减速器中,我似乎无法调用action.payload.step(该步骤将从我的动作中生成,它应该代表在调度时传递的值。

只是为了确认,我想在我的减速器中添加步骤,因为我不应该调用+ 1,我应该传递步骤值。

减速器:

import {
INCREMENT_REQUEST,
INCREMENT_SUCCESS,
INCREMENT_FAILURE,
DECREMENT_REQUEST,
DECREMENT_SUCCESS,
DECREMENT_FAILURE,
} from "../actions/actionTypes";
const initialState = {
value: 0,
loading: null,
error: null,
};
const counterReducers = (state = initialState, action) => {
switch (action.type) {
case INCREMENT_REQUEST:
return { ...state, loading: true, error: null };
case INCREMENT_SUCCESS:
return {
...state,
value: state.value + 1,
loading: false,
error: null,
};
case INCREMENT_FAILURE:
return { ...state, error: action.error };
case DECREMENT_REQUEST:
return { ...state, loading: true, error: null };
case DECREMENT_SUCCESS:
return {
...state,
value: state.value - 1,
loading: false,
error: null,
};
case DECREMENT_FAILURE:
return { ...state, error: action.error };
default:
return state;
}
};
export default counterReducers;

动作:

import { INCREMENT_REQUEST, DECREMENT_REQUEST } from "./actionTypes";
export const incrementAction = (step) => {
return {
type: INCREMENT_REQUEST,
payload: {
step: step,
},
};
};
export const decrementAction = (step) => {
return {
type: DECREMENT_REQUEST,
payload: {
step: step,
},
};
};
容器:

import { useSelector, useDispatch } from "react-redux";
import CounterComponent from "../components/CounterComponent";
const CounterContainer = () => {
const counter = useSelector((state) => state.counterReducers);
const dispatch = useDispatch();
return <CounterComponent counter={counter} dispatch={dispatch} />;
};
export default CounterContainer;
UI组件/子组件:
import React from "react";
import { decrementAction, incrementAction } from "../actions";
const CounterComponent = ({ counter, dispatch }) => {
return (
<div>
<h1>Counter - Redux Saga Flow Example</h1>
<button onClick={() => dispatch(incrementAction(1))}>
Increment + 1
</button>
<button onClick={() => dispatch(decrementAction(1))}>
Decrement - 1
</button>
{counter.loading ? <div>loading</div> : <div>Count: {counter.value}</div>}
</div>
);
};
export default CounterComponent;

传奇:

import { takeEvery, call, put } from "redux-saga/effects";
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
function* incrementAsync() {
yield call(delay, 2000);
yield put({ type: "INCREMENT_SUCCESS" });
}
export function* watchIncrement() {
yield takeEvery("INCREMENT_REQUEST", incrementAsync);
}
function* decrementAsync() {
yield call(delay, 2000);
yield put({ type: "DECREMENT_SUCCESS" });
}
export function* watchDecrement() {
yield takeEvery("DECREMENT_REQUEST", decrementAsync);
}

任何帮助将不胜感激!

2021年9月15日更新

hey snazzyy,在你的评论之后,我检查了你的代码,缺少的部分是将有效负载从_REQUEST"传递到_SUCCESS"行动,

当你做yield put({ type: "INCREMENT_SUCCESS" })时,没有"有效载荷"对象,就是action.type在你的reducer里面,

takeEvery使用的函数将接收redux发送的原始动作对象,您只需要将其转发给最终动作,

像下面这样:

function* incrementAsync(action) {
yield call(delay, 2000);
yield put({ type: "INCREMENT_SUCCESS", payload: action.payload });
}
export function* watchIncrement() {
yield takeEvery("INCREMENT_REQUEST", incrementAsync);
}
function* decrementAsync(action) {
yield call(delay, 2000);
yield put({ type: "DECREMENT_SUCCESS", payload: action.payload });
}
export function* watchDecrement() {
yield takeEvery("DECREMENT_REQUEST", decrementAsync);
}

我还更新了codesandbox示例:https://codesandbox.io/s/redux-saga-counter-async-wsep6

==========原始答案

您是否将传奇初始化为中间件?

对于你的传奇,像这样:

export default function* rootSaga() {
yield all([
watchIncrement(),
watchDecrement()
])
}

和你的商店,像这样:

const sagaMiddleware = createSagaMiddleware()
const store = ...
sagaMiddleware.run(rootSaga)

如果你不启动它们,它们将不会监听存储中的事件并触发它们的动作

我用你的例子创建了一个CodeSandbox,并添加了"rootSaga",看起来工作正常:

https://codesandbox.io/s/redux-saga-counter-async-wsep6

关于它的演练可以在:https://redux-saga.js.org/docs/introduction/BeginnerTutorial

最新更新