Что такое mapDispatchToProps?

142

Я читал документацию для библиотеки Redux и имел этот пример,

В дополнение к чтению состояния компоненты контейнера могут отправлять действия. Аналогичным образом вы можете определить функцию с именем mapDispatchToProps(), которая получает метод dispatch() и возвращает реквизиты обратного вызова, которые вы хотите ввести в презентационный компонент.

Это фактически не имеет смысла. Зачем вам mapDispatchToProps, когда у вас уже есть mapStateToProps?

Они также предоставляют этот удобный пример кода:

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

Может кто-нибудь объяснить в простых мирянах, что это за функция и почему она полезна?

Теги:
redux

5 ответов

241
Лучший ответ

Я чувствую, что ни один из ответов не кристаллизовался, почему mapDispatchToProps полезен.

На это можно ответить только в контексте шаблона container-component, который я нашел лучше всего понятым в первом чтении:

https://medium.com/@learnreact/container-components-c0e67432e005#.1a9j3w1jl

затем

http://redux.js.org/docs/basics/UsageWithReact.html

Вкратце, ваш components должен иметь дело только с отображением материала. только место, из которого они должны получить информацию, это их реквизит.

Отделяется от этого беспокойство:

  • как вы можете отобразить материал,
  • и как вы обрабатываете события.

Это то, что containers для.

Следовательно, "хорошо спроектированный" component в шаблоне выглядит следующим образом:

class FancyAlerter extends Component {
    sendAlert = () => {
        this.props.sendTheAlert()
    }

    render() {
        <div>
          <h1>Today Fancy Alert is {this.props.fancyInfo}</h1>
          <Button onClick={sendAlert}/>
        </div>
     }}

Посмотрите, как этот компонент получает информацию, которую он отображает из реквизита (который поступает из магазина redux через mapStateToProps), и он также получает свою функцию действия из своих реквизитов: sendTheAlert().

Что там, где mapDispatchToProps входит: в соответствующем container

FancyButtonContainer.js

function mapDispatchToProps(dispatch) {
    return({
        sendTheAlert: () => {dispatch(ALERT_ACTION)}
    })
}

function mapStateToProps(state} {
    return({fancyInfo: "Fancy this:" + state.currentFunnyString})
}

export const FancyButtonContainer = connect(
    mapStateToProps, mapDispatchToProps)(
    FancyAlerter
)

Интересно, видите ли вы, теперь это container [1], который знает о редукции и отправке и хранении, состоянии и... материалах.

component в шаблоне FancyAlerter, которому рендеринг не нужен никому из этого материала: он получает свой метод для вызова в onClick кнопки через свои реквизиты.

И... mapDispatchToProps было полезным средством, которое позволяет уменьшить контейнер, чтобы контейнер легко передавал эту функцию в обернутый компонент на своих реквизитах.

Все это очень похоже на пример todo в документах и ​​другой ответ здесь, но я попытался отобрать его в свете шаблона, чтобы подчеркнуть почему.

(Примечание: вы не можете использовать mapStateToProps для той же цели, что и mapDispatchToProps по той причине, что у вас нет доступа к dispatch внутри mapStateToProp. Таким образом, вы не можете использовать mapStateToProps, чтобы предоставить обернутому компоненту метод, который использует dispatch.

Я не знаю, почему они решили разбить его на две функции отображения - возможно, было бы более уместно иметь mapToProps(state, dispatch, props) IE одну функцию для выполнения обоих!


[1] Обратите внимание, что я намеренно явно назвал контейнер FancyButtonContainer, чтобы подчеркнуть, что это "вещь" - идентичность (и, следовательно, существование!) контейнера как "вещи" иногда теряется в сокращении

export default connect(...)

который показан в большинстве примеров

  • 3
    Я все еще хотел бы знать: что относительно требуемой функциональности не может быть обработано прямым вызовом store.dispatch из компонента?
  • 6
    @ user2130130 Нет. Это о хорошем дизайне. Если вы связали свой компонент с store.dispatch, то, когда вы решите выделить избыточный код или захотите использовать его в каком-либо месте, не основанном на Redxu (или в другом, о чем я не могу думать сейчас), вы застряли с много изменений. Ваш вопрос в целом звучит так: «Почему мы беспокоимся о« хороших методах проектирования »- вы получаете такую же функциональность, как только вы ее кодируете». Предоставляется mapDispatchToProps, так что вы можете писать хорошо спроектированные, четко отделенные компоненты.
Показать ещё 14 комментариев
22

Это в основном стенография. Поэтому вместо того, чтобы писать:

this.props.dispatch(toggleTodo(id));

Вы должны использовать mapDispatchToProps, как показано в вашем примере кода, а затем в другом месте:

this.props.onTodoClick(id);

или, более вероятно, в этом случае вы должны иметь это как обработчик события:

<MyComponent onClick={this.props.onTodoClick} />

Здесь полезное видео Дэн Абрамов: https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist

  • 0
    Спасибо. Мне также интересно, как диспетчеризация добавляется в реквизит?
  • 10
    Если вы не предоставите свою собственную функцию mapDispatch , Redux будет использовать значение по умолчанию. Эта функция mapDispatch умолчанию просто берет ссылку на функцию dispatch и выдает ее как this.props.dispatch .
Показать ещё 1 комментарий
16

mapStateToProps() - это утилита, которая помогает вашему компоненту получать обновленное состояние (которое обновляется некоторыми другими компонентами),
mapDispatchToProps() - это утилита, которая поможет вашему компоненту запускать событие действия (диспетчерское действие, которое может вызвать изменение состояния приложения).

2

mapStateToProps, mapDispatchToProps и подключение из библиотеки react-redux обеспечивает удобный способ доступа к вашему состоянию и функции отправки вашего магазина. Таким образом, в основном соединение - это компонент более высокого порядка, вы также можете использовать его как обертку, если это имеет смысл для вас. Таким образом, каждый раз, когда ваше состояние изменяется, mapStateToProps вызывается с вашим новым состоянием, а затем, когда вы создаете компонент обновления, вы запускаете функцию рендеринга для рендеринга вашего компонента в браузере. mapDispatchToProps также сохраняет ключевые значения в реквизитах вашего компонента, обычно они принимают форму функции. Таким образом вы можете вызвать изменение состояния из вашего компонента onClick, onChange events.

Из документов:

const TodoListComponent = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

const TodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList) 

Также убедитесь, что вы знакомы с Реагировать функции безстоящих лиц и Высшее -Закрыть компоненты

  • 0
    Таким образом, отправка, как событие в принципе?
  • 2
    Это может быть связано с событием, отправка только функция и единственный способ изменить состояние приложения. mapStateToProps - это один из способов представить функцию отправки вашего магазина в React Component. Также обратите внимание, что connect не является частью redux, на самом деле это всего лишь утилита, и шаблонная библиотека под названием response-redux сокращает работу для реагирования и redux. Вы можете достичь того же результата без реакции-избыточности, если передадите свой магазин от корневого компонента реакции дочерним элементам.
0

mstp получает state и props и позволяет извлекать реквизиты из состояния для перехода к компоненту.

mdtp получает dispatch и props и предназначен для того, чтобы вы могли привязать создателей действий к отправке, поэтому, когда вы выполняете результирующую функцию, действие будет удалено.

Я нахожу, что это только избавляет вас от необходимости выполнять dispatch(actionCreator()) внутри вашего компонента, что делает его более легким для чтения.

https://github.com/reactjs/react-redux/blob/master/docs/api.md#arguments

  • 0
    Спасибо, но какова ценность метода dispatch ? Откуда это взялось?
  • 0
    ой. Диспетчеризация в основном заставляет действие запускать однонаправленный поток притока / потока. Другие ответы, кажется, ответили на ваш вопрос лучше, чем этот.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню