connect()method просто предоставляет пользователю способ подключить компонент к хранилищу redux. Он предоставляет свой связанный компонент с частями данных, которые ему нужны из магазина, и функциями, которые он может использовать для отправки действий в магазин. Он не изменяет переданный ему класс компонента; вместо этого он возвращает новый связанный класс компонента, который обертывает переданный вами компонент.

Когда использовать connect ()

Как правило, реагирующие компоненты можно разделить на 2 типа:

  1. Презентационные компоненты - это глупые компоненты пользовательского интерфейса, которые заботятся только о том, как все выглядит, и не осведомлены о состоянии Redux.
  2. Компоненты контейнера - это компоненты, которые отвечают за функциональность и полностью осведомлены о состоянии Redux. Они часто отправляют действия Redux и подписываются на изменения в состоянии Redux.

Как использовать connect ()

function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)

connect принимает четыре различных параметра, все необязательные. Условно их называют:

  1. mapStateToProps?: Function
  2. mapDispatchToProps?: Function | Object
  3. mergeProps?: Function
  4. options?: Object

connect также может быть вызван без параметров, поскольку все они являются необязательными

connect()(MyFirstComponent)// which is equivalent with
connect(null, null)(MyFirstComponent) 
// or
connect(mapStateToProps /** no second argument */)(MyFirstComponent)
// or
connect(mapStateToProps, null, mergeProps, options)(MyFirstComponent)

1 — mapStateToProps?: (state, ownProps?) => Object

Если этот метод определен, это означает, что компонент собирается подписаться на состояние redux, и он будет срабатывать при изменении состояния. Результатом mapStateToProps должен быть простой объект, который будет объединен в свойства обернутого компонента. Если вы не хотите подписываться на обновления магазина, передайте null или undefined вместо mapStateToProps.

Параметры

- state текущее состояние редукции

- ownProps - если ваш метод имеет 2 параметра, при каждом вызове метода ему будет присвоено состояние хранилища в качестве первого параметра (state), а свойства компонента-оболочки в качестве второго параметра ( ownProps).

return mapStateToProps определяет, будет ли подключенный компонент повторно визуализирован с использованием === сравнения (проверка «неглубокого равенства») для каждого поля возвращаемого объекта. Если какое-либо из полей изменилось, то ваш компонент будет повторно отрисован, чтобы он мог получать обновленные значения как реквизиты.

2 — mapDispatchToProps?: Object | (dispatch, ownProps?) => Object

Это может быть объект, функция или значение null.

Параметры

- dispatch отправка вашего магазина, которую вы можете использовать для отправки действий

- ownProps - аналогично ownProps, переданному для mapStateToProps

Возврат ваших mapDispatchToProps функций рассматривается как dispatchProps. Он будет добавлен в качестве свойств к подключенному компоненту.

Note - вы можете определить mapDispatchToProps как функцию или как объект. В качестве функции это будет выглядеть примерно так

import { updatUserInfo, setCurrentPage } from '../../actions-creators'
function mapDispatchToProps(dispatch, ownProps) {
  return bindActionCreators({
    setCurrentPage,
    updatUserInfo
  },dispatch)
}
//or
const mapDispatchToProps = (dispatch, ownProps) => {
  return bindActionCreators({
    setCurrentPage,
    updatUserInfo
  },dispatch)
}

Вместо этого, если вы хотите использовать обозначение объекта, это будет выглядеть примерно так

import { updatUserInfo, setCurrentPage } from '../../actions'
const mapDispatchToProps = {
    setCurrentPage,
    updatUserInfo
}

В этом случае React-Redux связывает dispatch вашего магазина с каждым из создателей действий, используя bindActionCreators.

3 — mergeProps?: (stateProps, dispatchProps, ownProps) => Object

Если указано, определяет, как определяются окончательные свойства для вашего собственного обернутого компонента. Если вы не предоставите mergeProps, ваш обернутый компонент по умолчанию получит { ...ownProps, ...stateProps, ...dispatchProps }.

Эти параметры являются результатом props, mapStateToProps(), mapDispatchToProps() компонента оболочки соответственно.

Значение return mergeProps обозначается как mergedProps, и поля будут использоваться в качестве свойств для обернутого компонента.

4 — options?: Object

{  
  context?: Object,  
  pure?: boolean,  
  areStatesEqual?: Function,  
  areOwnPropsEqual?: Function,  
  areStatePropsEqual?: Function,  
  areMergedPropsEqual?: Function,  
  forwardRef?: boolean,
}

context - здесь вы можете передать настраиваемый контекст

pure - если options.pure истинно (также значение по умолчанию), connect выполняет несколько проверок равенства, которые используются, чтобы избежать ненужных вызовов mapStateToProps, mapDispatchToProps, mergeProps и, в конечном итоге, render. К ним относятся areStatesEqual, areOwnPropsEqual, areStatePropsEqual и areMergedPropsEqual. Хотя значения по умолчанию, вероятно, подходят в 99% случаев, вы можете переопределить их с помощью пользовательских реализаций по соображениям производительности или по другим причинам.

areStatesEqual: (next: Object, prev: Object) => boolean — В чистом виде сравнивает состояние входящего хранилища с его предыдущим значением.

Это может быть действительно полезно, если вы хотите внимательно следить за тем, когда компонент должен быть обновлен.

const areStatesEqual = (next, prev) => prev.books.favAuthors === next.books.favAuthors

Вышеупомянутая настраиваемая реализация гарантирует, что она будет игнорировать изменения состояния для всего, кроме списка favAuthors в состоянии.

areOwnPropsEqual: (next: Object, prev: Object) => boolean — В чистом виде сравнивает входящие свойства с его предыдущим значением.

areStatePropsEqual: (next: Object, prev: Object) => boolean — В чистом виде сравнивает результат mapStateToProps с его предыдущим значением.

areMergePropsEqual: (next: Object, prev: Object) => boolean — В чистом виде сравнивает результат mergeProps с его предыдущим значением.

forwardRef: boolean — Если это было передано как истина в connect, добавление ссылки к подключенному компоненту-оболочке фактически вернет экземпляр обернутого компонента.

Что будет возвращать connect ()

Он возвращает функцию-оболочку, которая принимает ваш компонент и возвращает компонент-оболочку с дополнительными добавленными реквизитами.

Пример использования

import { updatUserInfo, setCurrentPage } from '../../actions-creators'
export class UserInfoSheet extends Component {
const buildUserActions = (userId) => {
  this.props.setCurrentPage(1)
  this.props.updatUserInfo(userId)
}
render() {
  return (
    <Modal open={this.props.isOpen} >
      <div style={style.container}>
       {this.props.currentPageIndex === 0 ? <EnterUserInfo/> :   <UserActions inProgress={this.props.inProgress} bottomActionsData={this.buildUserActions(this.props.userId)} />}
      </div>
    </Modal>
    )
  }
}
const mapStateToProps = (state) => {
  return {
    isOpen: state.modals.userDialog.isOpen,
    currentPageIndex: state.modals.userDialog.currentPageIndex,
    userId: state.userInfo.id
    inProgress: state.userDialog.inProgress
  }
}
const mapDispatchToProps = (dispatch, ownProps) => {
  return bindActionCreators({
    setCurrentPage,
    updatUserInfo
  },dispatch)
}
export default connect( mapStateToProps, mapDispatchToProps)(UserInfoSheet)

Часто задаваемые вопросы - о чем следует помнить

Если вы не передаете методу mapStateToProps параметры или 2 параметра, вы можете получить доступ к ownProps, как показано ниже.

const mapStateToProps = (state, ownProps) => {  
  console.log(state) // state  
  console.log(ownProps) // ownProps
}
//or 
function mapStateToProps() {  
  console.log(arguments[0]) // state  
  console.log(arguments[1]) // ownProps
}
//or 
const mapStateToProps = (...args) => {  
  console.log(args[0]) // state  
  console.log(args[1]) // ownProps
}

иначе, если вы явно передадите только 1 параметр, вы не сможете получить доступ к ownProps.

const mapStateToProps = (state) => {  
  console.log(state) // state  
  console.log(arguments[1]) // undefined
}

Хорошие чтения

При написании этой статьи мне действительно помогли следующие статьи, и вы можете просмотреть их, чтобы узнать о них подробнее.

  • https://react-redux.js.org/using-react-redux/connect-mapdispatch
  • https://react-redux.js.org/api/connect
  • https://blog.logrocket.com/react-redux-connect-when-and-how-to-use-it-f2a1edab2013/

Не забудьте подписаться на публикацию The Lean Programmer Publication, чтобы увидеть больше таких статей, и подпишитесь на нашу рассылку tinyletter.com/TheLeanProgrammer