bindActionCreators и mapDispatchToProps - нужны ли они мне? - PullRequest
2 голосов
/ 07 марта 2019

Я смотрю на приложение 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 и использовать mapDispatchToProps ?

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Я сопровождающий Redux.

Да, во втором примере, который вы показали, используется форма "сокращение от объекта" mapDispatch.

Мы рекомендуем всегда использовать форму «Сокращения объекта» mapDispatch, если только у вас нет особых причин для настройки поведения отправки.

1 голос
/ 07 марта 2019

Лично я избегаю явного использования bindActionCreators.Я предпочитаю отправлять функции напрямую с помощью mapDispatchToProps, который внутренне использует 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);

Есть два случая, в которых вы будете явно использовать bindActionCreators, оба не являются оптимальными:

  1. Если у вас есть дочерний компонент для SearchBar, который не подключается к redux, но вы хотите передать действия, отправленные в качестве подпорки к нему, вы можете использовать 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);
Существует еще один маловероятный сценарий, в котором вы можете использовать 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)
...