【问题标题】:bindActionCreators and mapDispatchToProps - Do I need them?bindActionCreators 和 mapDispatchToProps - 我需要它们吗?
【发布时间】:2019-07-28 19:01:36
【问题描述】:

我正在查看一个 React-Redux 应用程序并尝试了解一切是如何工作的。

在其中一个组件中,我看到了以下代码行:

import { bindActionCreators } from "redux";

...

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchPhotos }, dispatch);
}

export default connect(
  null,
  mapDispatchToProps
)(SearchBar);

如果我将上面的代码更改为以下代码,一切仍然正常,没有任何错误:

function mapStateToProps(photos) {
  return { photos };
}

export default connect(
  mapStateToProps,
  { fetchPhotos }
)(SearchBar);

对我来说,似乎我使用 connect 的方式更容易理解,也不需要导入额外的库。

有什么理由要导入 bindActionCreators 并使用 ma​​pDispatchToProps?

【问题讨论】:

    标签: redux react-redux


    【解决方案1】:

    我是 Redux 维护者。

    是的,您展示的第二个示例使用了the "object shorthand" form of mapDispatch。

    我们建议始终使用 mapDispatch 的“对象速记”形式,除非您有特定的理由来自定义调度行为。

    【讨论】:

    • 对不起,但我的意思是,在我的第二个示例中,我根本不使用 mapDispatchToProps。相反,我使用 mapStateToProps,我仍然可以将操作 fetchPhotos 传递给我的组件。现在我的问题是,当我可以使用 mapStateToProps 时,为什么还要使用 mapDispatchToProps。我有什么理由应该使用 mapDispatchToProps 而不是 mapStateToProps?
    • connect 的第二个参数称为mapDispatchToProps,它旨在让您定义组件如何将操作分派到 Redux 存储。传递对象是“mapDispatch”的有效形式。 mapStateToProps 是一个完全不同的参数,旨在让您定义组件从 Redux 存储接收的数据。它们不是一回事。
    • 现在我明白了。当我将 { fetchPhotos } 作为对象传递时,就像使用 mapDispatchToProps。但是,通过将操作 fetchPhotos 作为对象传递,我不再需要编写 mapDispatchToProps。对吗?
    • 基本上是的。
    【解决方案2】:

    我个人避免明确使用 bindActionCreators。我更喜欢使用内部使用 bindActionCreators 的 mapDispatchToProps 直接调度函数。

    const mapStateToProps = state => ({
     photos: state.photos.photos
    });
    
    const mapDispatchToProps = dispatch => ({
      fetchPhotos: () => dispatch(fetchPhotos())
      // ...Other actions from other files
    });
    
    export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);
    

    在两种情况下,您将明确使用 bindActionCreators,这两种情况都不是最佳实践:

    1. 如果 SearchBar 的子组件没有连接到 redux,但您想将 action dispatch 作为 props 传递给它,则可以使用 bindActionCreators。 最佳实践与示例 I 相同。您可以直接将 this.props.fetchPhotos 传递给子组件,而无需使用 bindActionCreators。
    class SearchBar extends React.Component {
      render() {
        return (
          <React.Fragment>
             <ChildComponentOfSearchBar fetchPhotos={this.props.fetchPhotos} />
          </React.Fragment>
        )
      }
    }
    
    const mapStateToProps = state => ({
     photos: state.photos.photos
    });
    
    const mapDispatchToProps = () => bindActionCreators({ fetchPhotos }, dispatch);
    
    export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);
    
    1. 还有另一种不太可能的情况,您可以使用 bindActionCreators,在组件内定义 actionCreator。这是不可维护的,也不是一个好的解决方案,因为操作类型是硬编码的并且不可重用。
    class SearchBar extends React.Component {
      constructor(props) {
       super(props);
       this.fetchPhotosAction = bindActionCreators({ fetchPhotos: this.searchFunction }, dispatch);
      }
    
      searchFunction = (text) => {
       return {
         type: ‘SEARCH_ACTION’,
         text
       }
      }
    
      render() {
        return (
          <React.Fragment>
            // Importing selectively
            <ChildComponentOfSearchBar fetchPhotos={this.fetchPhotosAction} />
          </React.Fragment>
        )
      }
    }
    
    const mapStateToProps = state => ({
     photos: state.photos.photos
    });
    
    export default connect(mapStateToProps, null)(SearchBar)
    

    【讨论】:

    • 谢谢。但是 mapDispatchToProps 呢?我应该什么时候使用它?如果我总是使用 mapStateToPprops 可以吗?
    • mapDispatchToProps 应该在您使用来自动作创建者的东西时使用。如果您不打算调度任何触发全局状态更改的操作,那么您根本不需要 mapDispatchToProps。
    • 好的,我明白了。但似乎我可以代替 mapDispatchToProps 使用 mapStateToProps 并且它也可以工作。为什么要使用 mapDispatchToProps?
    • 我认为您对 stateToProps 和 dispatchToProps 感到困惑。要访问存储在 global-redux-store 状态中的数据/值,我们使用 mapStateToProps。为了获取 redux store 修改全局状态的 action 函数,我们使用 mapDispatchToProps..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 2017-11-13
    • 2023-02-14
    • 1970-01-01
    相关资源
    最近更新 更多