使用bindActionCreators,this.props.dispatch in react-redux disptach vs redux

时间:2018-03-14 08:24:12

标签: 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)

另一个代码使用如下:

        function mapDispatchToProps(dispatch) {
          let actions = bindActionCreators({ getApplications });
          return { ...actions, dispatch };
        }           

为什么以前使用bindActionCreators的代码,不需要disptach参数?

我已经尝试过这种方式来调度this.props(但没有工作):

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

const withState = connect(
  null ,
  mapDispatchToProps,
)(withGraphqlandRouter);

为什么我不得不改变我的旧方式:

const withState = connect(
  null ,
  { appSubmitStart,  appSubmitStop}
)(withGraphqlandRouter);

为了得到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';

使用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
};

有人能解释我吗?我怎么能像创作者一样发送同样的烦恼?

2 个答案:

答案 0 :(得分:2)

我对您的代码进行了一些更改,请尝试使用

import * as Actions from './actionCreators'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'


const mapStateToProps = (state)=>(
    {
        todos: state.todos
    }
)

const mapDispatchToProps = (dispatch)=> (
    bindActionCreators(Actions, dispatch) 
)

export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)

答案 1 :(得分:0)

首先,让我们对这里的一些关键概念清醒一下:

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

关于代码上方发生的事情:

组件将不会收到带有自定义dispatch的{​​{1}}

在此处的代码中:

mapDispatchToProps

您要提供自己的const mapDispatchToProps = (dispatch) => { return bindActionCreators( { appSubmitStart, appSubmitStop, dispatch }, // a bit problematic here, explained later dispatch ); // to set this.props.dispatch }; ,因此您的组件将接收mapDispatch。相反,它将依赖您返回的对象来包含由dispatch包裹起来的动作创建者。

您可能会觉得在这里容易出错。建议您直接使用对象的简写形式,输入组件需要的所有动作创建者。 React-Redux为您将每个绑定有dispatch的对象,并且不再给dispatch。 (有关更多讨论,请参见this issue。)

编写自定义的dispatch并手动注入mapState

但是,如果您确实确实需要dispatch以及其他动作调度程序,则需要通过以下方式定义dispatch

mapDispatch

使用const mapDispatchToProps = (dispatch) => { return { appSubmitStart: () => dispatch(appSubmitStart), appSubmitStop: () => dispatch(appSubmitStop), dispatch, }; };

这正是bindActionCreators所做的。因此,您可以使用Redux的bindActionCreators进行简化:

bindActionCreators

如上所述,在第一个参数中包含const mapDispatchToProps = (dispatch) => { return bindActionCreators( { appSubmitStart, appSubmitStop }, // do not include dispatch here dispatch ); }; 的问题是实际上它被dispatch包裹了。呼叫dispatch时将呼叫dispatch(dispatch)

但是,this.props.dispatch不会返回带有bindActionCreators的对象。它已传递给内部调用,它不会将其还给您。因此,您需要自己添加:

dispatch

希望它有所帮助!并且请让我知道这里是否不清楚:)