使用 bindActionCreators, this.props.dispatch 在 react-redux 调度 vs redux

DDa*_*ave 0 redux react-redux

我读过有关 bindActionCreators 的文章,我在这里编译了一份简历:

    import { addTodo,deleteTodo } from './actionCreators'
    import { bindActionCreators } from 'redux'

    function mapStateToProps(state) {
      return { todos: state.todos }
    }

    function mapDispatchToProps(dispatch) {
      return bindActionCreators({ addTodo, deleteTodo }, dispatch) 
    }

    *short way
        const mapDispatchToProps = {
          addTodo,
          deleteTodo
        }   
    export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
Run Code Online (Sandbox Code Playgroud)

另一个代码使用如下:

        function mapDispatchToProps(dispatch) {
          let actions = bindActionCreators({ getApplications });
          return { ...actions, dispatch };
        }           
Run Code Online (Sandbox Code Playgroud)

为什么以前带有 bindActionCreators 的代码不需要 disptach 参数?

我已经尝试过这种方式来获得 this.props 的调度(但不起作用):

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators ({ appSubmitStart,  appSubmitStop}, dispatch );
};

const withState = connect(
  null ,
  mapDispatchToProps,
)(withGraphqlandRouter);
Run Code Online (Sandbox Code Playgroud)

为什么我不得不改变我以前的捷径:

const withState = connect(
  null ,
  { appSubmitStart,  appSubmitStop}
)(withGraphqlandRouter);
Run Code Online (Sandbox Code Playgroud)

为了得到 this.props.dispatch()?因为我需要在具有 js 函数的库中为隔离的动作创建者使用调度。我的意思是在我不需要使用“bindActionCreators”之前,请阅读此文档:

https://redux.js.org/api-reference/bindactioncreators

“bindActionCreators 的唯一用例是当你想将一些动作创建者传递给一个不知道 Redux 的组件时,你不想将 dispatch 或 Redux 存储传递给它。”

我正在进口:

import { bindActionCreators } from 'redux';
import { connect  } from 'react-redux';
Run Code Online (Sandbox Code Playgroud)

使用 redux pure 和 react-redux 有什么区别?我的新代码中真的需要“bindActionCreators”吗?因为没有这个我看不到 this.props.dispatch()

更新:

我找到了这个解决方案来让 this.props.dispatch 工作:

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators ({ appSubmitStart,  appSubmitStop, dispatch }, dispatch );  // to set this.props.dispatch
};
Run Code Online (Sandbox Code Playgroud)

有没有人可以解释我?我如何像创作者一样发送相同的 distpach?

小智 5

首先让我们理清这里的一些关键概念:

  • bindActionCreators是 Redux 提供的一个工具。它将每个动作创建者包装到一个调度调用中,以便可以直接调用它们。
  • dispatch是 Redux 存储的一个函数。它用于分派要存储的操作。
    • 当您使用对象简写 for 时mapState,React-Reduxdispatch使用商店的using Redux将它们包装起来bindActionCreators
  • connect是 React-Redux 提供的一个函数。它用于将您的组件连接到 Redux 存储。连接组件时:
    • 仅当您不提供自定义参数时,它才会注入dispatch您的组件。mapDispatchToProps

关于上面发生的事情你的代码:

组件不会收到dispatch定制的mapDispatchToProps

在此处的代码中:

const mapDispatchToProps = (dispatch) => {

  return bindActionCreators(
    { appSubmitStart, appSubmitStop, dispatch }, // a bit problematic here, explained later
    dispatch 
  );  // to set this.props.dispatch
};
Run Code Online (Sandbox Code Playgroud)

您提供的是您自己的mapDispatch,因此您的组件将不会收到dispatch。相反,它将依赖您返回的对象来包含由dispatch.

你可能觉得这里很容易出错。建议您直接使用对象速记,输入您的组件需要的所有动作创建器。React-Reduxdispatch为您绑定了每一个,并且不再提供dispatch。(有关更多讨论,请参阅此问题。)

编写自定义mapStatedispatch手动注入

但是,如果您确实需要dispatch与其他动作调度器一起使用,则需要以mapDispatch这种方式定义:

const mapDispatchToProps = (dispatch) => {
  return {
    appSubmitStart: () => dispatch(appSubmitStart),
    appSubmitStop: () => dispatch(appSubmitStop),
    dispatch,
  };
};
Run Code Online (Sandbox Code Playgroud)

使用 bindActionCreators

这正是bindActionCreators它的作用。因此,您可以通过使用 Redux 来简化一些bindActionCreators

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(
    { appSubmitStart, appSubmitStop }, // do not include dispatch here
    dispatch
  );
};
Run Code Online (Sandbox Code Playgroud)

如上所述,包含dispatch在第一个参数中的问题是它本质上被dispatch. 你会被调用dispatch(dispatch),当你调用this.props.dispatch

但是,bindActionCreators不返回带有 的对象dispatch。它被传入以供内部调用,它不会将其返回给您。所以你需要自己包括:

const mapDispatchToProps = (dispatch) => {
  return {
    ...bindActionCreators({appSubmitStart, appSubmitStop}, dispatch), 
    dispatch
  };
};
Run Code Online (Sandbox Code Playgroud)

希望有帮助!如果这里有任何不清楚的地方,请告诉我:)