注意我用setStepPositionIndex()
调用dispatch()
。当我删除dispatch(...)
成为setStepPositionIndex()
时,我希望setStepPositionIndex()
内的调度调用将接收它传递的普通操作对象并发送它......
或者,如果我在dispatch()
中移除setStepPositionIndex()
调用(并保持dispatch(setStepPositionIndex()
),同时明确返回其中的普通actionObj
,我期望与dispatch(setStepPositionIndex(actionObj))
成功发送
但是这个动作创作者的成功执行需要两个......为什么?
/* actions.js */
import { store } from "../store.js";
store.dispatch(setStepPositionIndex());
export const SET_STEP_POSITION_INDEX = "SET_STEP_POSITION_INDEX";
export const setStepPositionIndex = () => {
return (dispatch, getState) => {
const newSteps = getState().goals.currentGoalSteps.map((stepObj, index) => {
return { ...stepObj, positionIndex: index };
});
console.log("newSteps", newSteps);
/* [{step: "Step3", positionIndex: 0}
{step: "Step2", positionIndex: 1}
{step: "Step1", positionIndex: 2}] */
const actionObj = {
type: SET_STEP_POSITION_INDEX,
stepsArr: newSteps
};
// Unsuccessful alone ->
// return actionObj
// unsuccessful alone (removing dispatch() wrapper from setStepPositionIndex
//->
return dispatch(actionObj);
};
};
/*Reducer.js*/
import * as actions from "../Actions/actions";
import { store } from "../store";
if (action.type === "SET_STEP_POSITION_INDEX") {
return update(state, {
currentGoalSteps: { $set: action.stepsArr }
});
}
/*Store.js */
import { createStore, applyMiddleware, compose, combineReducers } from "redux";
import { ApolloClient } from "react-apollo";
import { createLogger } from "redux-logger";
import { reducer as formReducer } from "redux-form";
// import { client } from './index'
import thunk from "redux-thunk";
import * as Goal_Reducer from "./Reducers/Global_Reducer";
const logger = createLogger({
collapsed: (getState, action, logEntry) => !logEntry.error,
predicate: (getState, action) => !action.type.includes("@@redux-form")
});
const client = new ApolloClient();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export const store = createStore(
combineReducers({
goals: Goal_Reducer.goalReducer,
apollo: client.reducer(),
form: formReducer
}),
{}, //initial state
composeEnhancers(applyMiddleware(client.middleware(), thunk, logger))
);
哦,你只是问为什么你必须在你的thunk里做store.dispatch(setStepPositionIndex());
和dispatch()
。因为store.dispatch()
是使用正确的参数调用内部返回的thunk函数的原因,并且thunk内部的dispatch()
ing是将动作传播到reducers的内容。我可以看到这对新手来说会有多奇怪,因为dispatch()
正在做两件不同的事情。
首先你派遣thunk,然后thunk调度动作。
原始答案
当使用redux-thunk
并让你的动作创建者返回一个函数(return (dispatch, getState) => {
)时,你必须手动调用dispatch()
。你不能简单地从内部函数返回。这就是redux-thunk
的意思,即手动控制调度。
如果你不想这样做,而不是使用getState()
,你可以简单地从goals
或currentGoalSteps
作为参数传递你的组件中的动作。
因为当使用redux-thunk时,如果动作创建者返回一个函数而不是一个普通对象,则执行该函数并由dispatch
函数返回其返回值。 setStepPositionIndex()
返回的函数不是普通对象,因此store.dispatch(setStepPositionIndex())
的结果将是:
{
type: SET_STEP_POSITION_INDEX,
stepsArr: newSteps
}
实际上redux-thunk
只是一个中间件,它的代码非常简单
const thunk = store => next => action =>
typeof action === 'function'
? action(store.dispatch, store.getState)
: next(action)
您可以看到,当您传递函数时,中间件将执行它(使用dispatch
和getState
参数)并返回函数的值。
redux-thunk
对于在某些条件下或延迟后派遣行动很有用,在你的情况下,我认为你真的不需要redux-thunk
,因为你是dispatching
一个动作取决于当前状态。您可以使用mapStateToProps
组件的connected
来检索商店的状态