首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Redux Thunk为什么我必须调用dispatch()两次?

Redux Thunk为什么我必须调用dispatch()两次?
EN

Stack Overflow用户
提问于 2018-09-04 06:23:29
回答 2查看 1.5K关注 0票数 0

注意,我使用dispatch()调用setStepPositionIndex()。当我将dispatch(...)删除为setStepPositionIndex()时,我希望setStepPositionIndex()中的分派调用将接收它传递的普通操作对象并分派它……

Alternatively,如果我删除setStepPositionIndex()中的dispatch()调用(并保留dispatch(setStepPositionIndex()),同时显式返回其中的纯actionObj,我将期望使用dispatch(setStepPositionIndex(actionObj))成功分派

,但成功执行此操作创建器需要同时...为什么?

代码语言:javascript
复制
   /* 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))
);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-04 06:38:40

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

首先你分派thunk,thunk分派动作。

原始答案

在使用redux-thunk并让操作创建者返回函数( return (dispatch, getState) => { )时,您必须手动调用dispatch()。您不能简单地从内部函数返回。这就是redux-thunk的意义所在,手动控制调度。

如果您不想这样做,您可以简单地使用goalscurrentGoalSteps作为参数从组件中分派您的操作,而不是使用getState()

票数 8
EN

Stack Overflow用户

发布于 2018-09-04 06:45:57

因为在使用redux-thunk时,如果操作创建者返回一个函数而不是普通对象,则该函数将被执行,其返回值将由dispatch函数返回。setStepPositionIndex()返回的是函数,而不是普通对象,所以store.dispatch(setStepPositionIndex())的结果是:

代码语言:javascript
复制
{
  type: SET_STEP_POSITION_INDEX,
  stepsArr: newSteps
}

实际上,redux-thunk只是一个中间件,它的代码非常简单

代码语言:javascript
复制
const thunk = store => next => action =>
   typeof action === 'function'
     ? action(store.dispatch, store.getState)
     : next(action)

您可以看到,当您传递一个函数时,中间件将执行它(使用dispatchgetState参数)并返回函数的值。

在某些情况下或在延迟之后,redux-thunk对于分派操作非常有用,在你的情况下,我不认为你真的需要redux-thunk,因为你是根据当前状态来dispatching操作的。您可以使用connected组件的mapStateToProps来检索存储的状态

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52156726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档