it-swarm.com.de

Was ist mapDispatchToProps?

Ich habe die Dokumentation für die Redux-Bibliothek gelesen und sie enthält das folgende Beispiel:

Containerkomponenten können nicht nur den Status lesen, sondern auch Aktionen auslösen. Auf ähnliche Weise können Sie eine Funktion mit dem Namen mapDispatchToProps() definieren, die die Methode dispatch() empfängt und Callback-Requisiten zurückgibt, die Sie in die Präsentationskomponente einfügen möchten.

Das macht eigentlich keinen Sinn. Warum brauchen Sie mapDispatchToProps, wenn Sie bereits mapStateToProps haben?

Sie bieten auch dieses praktische Codebeispiel:

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

Kann bitte jemand dem Laien erklären, was diese Funktion ist und warum sie nützlich ist?

311
Code Whisperer

Ich glaube, keine der Antworten hat sich herauskristallisiert, warum mapDispatchToProps nützlich ist.

Dies kann wirklich nur im Kontext des Musters container-component beantwortet werden, das ich beim ersten Lesen am besten verstanden habe: Container Components dann sage with React .

Kurz gesagt, Ihr components soll sich nur mit der Anzeige von Dingen befassen. Der einzige Ort, von dem sie Informationen erhalten sollen, sind ihre Requisiten.

Getrennt von "anzeigen" (Komponenten) ist:

  • wie man das zeug zur anzeige bringt,
  • und wie Sie mit Ereignissen umgehen.

Dafür sind containers da.

Daher sieht ein "gut gestaltetes" component im Muster folgendermaßen aus:

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

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

Sehen Sie, wie diese Komponente die angezeigten Informationen von Requisiten erhält (die über mapStateToProps aus dem Redux-Store kamen) und ihre Aktionsfunktion auch von ihren Requisiten: sendTheAlert().

Hier kommt mapDispatchToProps ins Spiel: im entsprechenden 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
)

Ich frage mich, ob Sie jetzt sehen können, dass es das container1 ist, das über Redux und Versand Bescheid weiß und es speichert und ... Sachen.

Das component in dem Muster, FancyAlerter, das das Rendering ausführt, muss nichts davon wissen: Es erhält seine Methode, um onClick der Schaltfläche über dessen aufzurufen Requisiten.

Und ... mapDispatchToProps war das nützliche Mittel, das Redux bietet, um dem Container diese Funktion auf einfache Weise in die verpackte Komponente seiner Requisiten zu übertragen.

All dies ähnelt sehr dem ToDo-Beispiel in der Dokumentation und einer anderen Antwort hier, aber ich habe versucht, es im Licht des Musters darzustellen, um warum hervorzuheben.

(Hinweis: Sie können mapStateToProps nicht für den gleichen Zweck wie mapDispatchToProps verwenden, da Sie in dispatch keinen Zugriff auf mapStateToProp haben Verwenden Sie mapStateToProps nicht, um der umschlossenen Komponente eine Methode zuzuweisen, die dispatch verwendet.

Ich weiß nicht, warum sie beschlossen haben, es in zwei Zuordnungsfunktionen zu unterteilen - es könnte ordentlicher gewesen sein, mapToProps(state, dispatch, props) IE eine Funktion zu haben, um beides zu tun!


1 Beachten Sie, dass ich den Container FancyButtonContainer ausdrücklich benannt habe, um hervorzuheben, dass es sich um ein "Ding" handelt - die Identität (und damit die Existenz!) Des Containers da "ein Ding" manchmal in der Kurzschrift verloren geht

export default connect(...) ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Syntax, die in den meisten Beispielen gezeigt wird

524
GreenAsJade

Es ist im Grunde eine Kurzschrift. Also anstatt schreiben zu müssen:

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

Sie würden mapDispatchToProps wie in Ihrem Beispielcode gezeigt verwenden und an anderer Stelle schreiben:

this.props.onTodoClick(id);

oder wahrscheinlicher, in diesem Fall würden Sie das als den Ereignishandler haben:

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

Hier gibt es ein hilfreiches Video von Dan Abramov: https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist

70
hamstu

mapStateToProps() ist ein Dienstprogramm, mit dessen Hilfe Ihre Komponente den Aktualisierungsstatus erhält (der von einigen anderen Komponenten aktualisiert wird).
mapDispatchToProps() ist ein Dienstprogramm, mit dem Ihre Komponente ein Aktionsereignis auslösen kann (Auslösen einer Aktion, die eine Änderung des Anwendungsstatus verursachen kann).

48

mapStateToProps, mapDispatchToProps und connect aus der react-redux Bibliothek bieten eine bequeme Möglichkeit, auf Ihre state und dispatch Funktion Ihres Geschäfts zuzugreifen. Damit connect im Grunde genommen eine übergeordnete Komponente ist, können Sie sich auch als Wrapper vorstellen, wenn dies für Sie sinnvoll ist. So wird jedes Mal, wenn Ihr state geändert wird, mapStateToProps mit Ihrem neuen state aufgerufen und anschließend, wenn Sie props aktualisieren, die Renderfunktion ausgeführt, um Ihre Komponente im Browser zu rendern. mapDispatchToProps speichert auch Schlüsselwerte in props Ihrer Komponente, normalerweise in Form einer Funktion. Auf diese Weise können Sie state Änderungsereignisse aus Ihrer Komponente onClick, onChange auslösen.

Aus Dokumenten:

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) 

Stellen Sie außerdem sicher, dass Sie mit Reagieren Sie auf zustandslose Funktionen und Komponenten höherer Ordnung vertraut sind

18
Vlad Filimon

mapStateToProps empfängt state und props und ermöglicht Ihnen, Requisiten aus dem Status zu extrahieren, die an die Komponente übergeben werden sollen.

mapDispatchToProps empfängt dispatch und props und ist dafür gedacht, Aktionsersteller an den Versand zu binden, sodass die Aktion beim Ausführen der resultierenden Funktion ausgelöst wird.

Ich finde, dies erspart Ihnen nur, dass Sie dispatch(actionCreator()) in Ihrer Komponente ausführen müssen, was das Lesen ein wenig erleichtert.

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

2
Harry Moreno

Angenommen, es gibt eine Aktion für Redux als:

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

Wenn Sie es importieren,

import {addTodo} from './actions';

class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

const mapDispatchToProps = dispatch => {
    return {
      onTodoClick: () => { // handles onTodoClick prop's call here
        dispatch(addTodo())
      }
    }
}

export default connect(
    null,
    mapDispatchToProps
)(Greeting);

Wie der Funktionsname mapDispatchToProps() sagt, ordnen Sie dispatch die Aktion den Requisiten (Requisiten unserer Komponente) z

Daher ist prop onTodoClick ein Schlüssel für die Funktion mapDispatchToProps, mit der delegiert wird, dass die Aktion addTodo ausgelöst wird.

Auch wenn Sie den Code kürzen und die manuelle Implementierung umgehen möchten, können Sie dies tun.

import {addTodo} from './actions';
class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.addTodo();
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

export default connect(
    null,
    {addTodo}
)(Greeting);

Welches genau bedeutet

const mapDispatchToProps = dispatch => {
    return {
      addTodo: () => { 
        dispatch(addTodo())
      }
    }
}
1
Meet Zaveri