bindActionCreators and mapDispatchToProps - Do I need them?

本小妞迷上赌 提交于 2020-01-04 15:11:13

问题


I'm looking at a React-Redux app and try to understand how everything is working.

Inside one of the components, I saw these lines of code:

import { bindActionCreators } from "redux";

...

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

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

If I change the above code to the following, everything still works, without any errors:

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

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

To me, it seems that my way of using connect is easier to understand and it also doesn't need to import an extra library.

Is there any reasons, to import bindActionCreators and use mapDispatchToProps?


回答1:


I'm a Redux maintainer.

Yes, the second example you showed uses the "object shorthand" form of mapDispatch.

We recommend always using the “object shorthand” form of mapDispatch, unless you have a specific reason to customize the dispatching behavior.




回答2:


I personally avoid using bindActionCreators explicitly. I prefer to directly dispatch the functions with mapDispatchToProps which internally uses bindActionCreators.

const mapStateToProps = state => ({
 photos: state.photos.photos
});

const mapDispatchToProps = dispatch => ({
  fetchPhotos: () => dispatch(fetchPhotos())
  // ...Other actions from other files
});

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

There are two cases in which you'll use bindActionCreators explicitly, both are not best practices:

  1. If you have a child component to SearchBar that does not connect to redux, but you want to pass down action dispatches as props to it, you can use bindActionCreators. Best practice would be doing same with example I. You can just pass this.props.fetchPhotos to childcomponent directly without using 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. There is another unlikely scenario where you can use bindActionCreators, defining actionCreator inside the component. This isn't maintainable & is not a good solution since action types are hard coded and not reusable.
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)


来源:https://stackoverflow.com/questions/55034527/bindactioncreators-and-mapdispatchtoprops-do-i-need-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!