Что такое mapDispatchToProps?

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

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

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

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

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

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

5 ответов


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

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

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

затем

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

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

отделено от "отображения материала" (компонентов):

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

что это 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 и отправки и хранения и государства и ... материал.

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

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

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

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

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


[1] Обратите внимание, что I намеренно явно названный контейнер 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 update component запустит функцию рендеринга для рендеринга вашего компонента в браузере. mapDispatchToProps также хранит ключ-значение the props компонента, как правило, они принимают форму функции. Таким образом, вы можете вызвать state изменение от вашего компонента onClick, onChange событий.

из docs:

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