本文介绍了Redux Thunk - 为什么我必须调用 dispatch() 两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意我用 dispatch() 调用了 setStepPositionIndex().当我删除 dispatch(...) 成为 setStepPositionIndex()我希望 setStepPositionIndex() 中的调度调用将接收它传递的普通操作对象并调度它...

Note I'm calling setStepPositionIndex() with dispatch(). When I remove dispatch(...) to become just setStepPositionIndex()I would expect that the dispatch call within setStepPositionIndex() would receive the plain action object it's passed and dispatch it...

或者,如果我删除 setStepPositionIndex() 中的 dispatch() 调用(并保留 dispatch(setStepPositionIndex()) 同时在其中显式返回纯 actionObj,我希望使用 dispatch(setStepPositionIndex(actionObj))

Alternatively, if I remove the dispatch() call within setStepPositionIndex() (and keep dispatch(setStepPositionIndex()) while explicitly returning plain actionObj within it, I would expect a successful dispatch with 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))
);

推荐答案

哦,你只是问为什么你必须做 store.dispatch(setStepPositionIndex()); 而仍然是 dispatch() 在你的 thunk 中.因为 store.dispatch() 是使用正确参数调用内部返回的 thunk 函数的原因,而在 thunk 中的 dispatch() 是将动作传播到减速器.我可以看出这对新手来说是多么奇怪,因为 dispatch() 正在做两件不同的事情.

Oh, you're just asking why you have to do store.dispatch(setStepPositionIndex()); and still dispatch() inside your thunk. Because store.dispatch() is what makes the inner returned thunk function get called with the right arguments, and dispatch()ing inside the thunk is what propagates the action to the reducers. I can see how this would be strange to a newcomer, because dispatch() is doing two different things.

首先你调度 thunk,然后 thunk 调度动作.

First you dispatch the thunk, and the thunk dispatches the action.

原答案

当使用 redux-thunk 并且让你的动作创建者返回一个函数( return (dispatch, getState) => { )时,你必须手动调用 .你不能简单地从内部函数返回.这就是 redux-thunk 的重点,手动控制调度.

When using redux-thunk, and having your action creator returning a function ( return (dispatch, getState) => { ), then you must manually call dispatch(). You can't simply return from the inner function. That's the point of redux-thunk, to control the dispatch(es) manually.

如果你不想这样做,你可以简单地使用 goalscurrentGoalSteps 从你的组件分派你的动作,而不是使用 getState() 作为参数传入.

If you don't want to do this, instead of using getState(), you could simply dispatch your action from your component with goals or currentGoalSteps passed in as an argument.

这篇关于Redux Thunk - 为什么我必须调用 dispatch() 两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 18:52