Что такое mapDispatchToProps?


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

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

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

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

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

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

5 236

5 ответов:

я чувствую, что ни один из ответов кристаллизуется, почему 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's 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] который знает о redux и отправке и хранении и состоянии И... материал.

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

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

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

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

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


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

export default connect(...)

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

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

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

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

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

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

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) 

также убедитесь, что вы знакомы с реагируют функции без состояния и Компоненты Более Высокого Порядка

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

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

Я считаю, что это только спасает вас от необходимости делать dispatch(actionCreator()) в вашем компоненте, что делает его немного легче читать.

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