web-dev-qa-db-de.com

Ich kann nicht verstehen, warum Komponenten mit 'connect ()' Stateful reagieren

Meine Frage ist genauso wie der Titel. 

Nehmen wir an, ich habe den folgenden Code geschrieben.

class TODOList extends Component {  
  render() {
    const {todos, onClick} = this.props;
    return (
      <ul>
            {todos.map(todo =>
                <Todo 
                    key={todo.id}
                    onClick={onClick}
                    {...todo}
                />
             )}
      </ul>
    );
  }
}


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


const mapDispatchToProps = (dispatch) => {  
    return {
        onClick(data){
          dispatch(complete(data)) 
        }
    }
}


export default connect(mapStateToProps,mapDispatchToProps)(TODOList); 

Nach der letzten Zeile exportiert dieser Code die TODOList-Komponente mit dem Status als Requisiten. Es ist nicht so, dass es state enthält, sondern nur state erhalten hat und sie als "Requisiten" haben wird, genau wie der Methodenname 'mapStateToProps' erklärt.

Im Medium Post ( https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 ), das von Dan Abramov geschrieben wurde, behandelt die Containerkomponente Daten als Status und als Eigentum darstellende Eigenschaften. Ist es nicht eine Präsentationskomponente, die Daten als Requisiten behandelt? Ich bleibe bei der Idee, dass der richtige Behälter wie unten sein sollte.

class CommentList extends React.Component {
  this.state = { comments: [] };

  componentDidMount() {
    fetchSomeComments(comments =>
      this.setState({ comments: comments }));
  }
  render() {
    return (
      <ul>
        {this.state.comments.map(c => (
          <li>{c.body}—{c.author}</li>
        ))}
      </ul>
    );
  }
}

Ich bin mir nicht sicher, warum die API von rea-redux 'mapStateToProps' genannt wurde, als ich versuchte, eine 'stateful'-Container-Komponente zu erstellen (keine Daten nach Eigenschaft zu behandeln)

9
Rhee

Zunächst sind diese Richtlinien nicht Teil der Bibel
Sie sollten Code schreiben, der für YOU und Ihr TEAM leicht zu begründen ist. 

Ich denke, dass Sie etwas vermissen. Ein Redux-Container unterscheidet sich von einem reagierenden Container.
Ich meine, connect wird den Container für Sie erstellen. Dies bedeutet nicht, dass die Wrap-Komponente is ein Container ist. 

Grundsätzlich können Sie beide Versionen aus derselben Datei exportieren, den Container (verbundene Version) und die Präsentationsversion (die nicht verbundene Version). 

Eine andere Sache, die normalerweise Leute abwirft, ist der Name der Funktion und des Arguments von mapStateToProps.
Ich ziehe den Namen mapStoreToProps wie in vor 

ordnen Sie den redux-Speicher den Requisiten der Komponente zu. 

der Name state kann verwirrend sein, wenn wir uns im Kontext von react befinden.

Bearbeiten
Als Folgemaßnahme zu Ihrem Kommentar: 

Ich wusste gar nicht, dass diese beiden tatsächlich anders sind. Könnten Sie mir bitte weitere Einzelheiten mitteilen?

Sie unterscheiden sich darin, wie connect einen "Container" für Sie erstellt. 

connect ist eine Komponente hoher Ordnung, die die Container-Komponente für uns mit allen Subskriptionslogik + Funktionen erstellt, um Teile des Speichers und der Aktionsersteller als Requisiten an ihre Kinder zu übergeben (mapStateToProps & mapDispatchToProps).

Ein "normaler" Container bezieht sich normalerweise auf eine Komponente, die Sie von Hand schreiben. In diesem Fall geht es nicht darum, wie die Dinge aussehen sollen, sondern um bestimmte Logik der App.

Wie für die anderen Kommentare

Der Verbindungs-HoC von React-Redux fügt die Eigenschaften, die Sie anfordern können, in Ihre Komponente ein. Sie gibt eine neue Komponente zurück, die um Ihre Komponente gewickelt ist, sodass sie Ihre Komponente aktualisieren kann, wenn der Status, den Sie am redux store interessiert, geändert wird

Wie ich oben erwähnt habe, trifft dies teilweise zu. Es ist nicht nur das Einfügen der Eigenschaften in unsere Komponente, das Abonnieren des Speichers, das Abrufen der Provider (über context) und das Erzielen all dieser Optimierungen, sodass wir dies nicht selbst tun müssen. 

Ich bin mir nicht sicher, wie mapStateToProps jemanden verwirren kann. Es handelt sich um eine staatliche Verwaltungsbibliothek

Ich habe einige Entwickler gesehen, die dies missverstanden haben, weil react eine state und redux eine store hat (zumindest wurde es in den meisten Tutorials und Dokumentationen so genannt).
Dies kann für einige Leute verwirrend sein, die neu in react oder redux sind. 

Edit 2

Es war etwas verwirrend wegen des Satzes "das bedeutet nicht, dass die Wrap-Komponente ein Container ist." Warum ist die umwickelte Komponente kein Container? Ist eine von connect erstellte Komponente nicht auch ein Container?

Ich meine, dass die umschlossene Komponente, die Sie geschrieben haben, muss nicht sein muss einen Container.
Sie können eine "Presentation" -Komponente anschließen: 

const Link = ({ active, children, onClick }) => {
  if (active) {
    return <span>{children}</span>
  }

  return (
    <a
      href=""
      onClick={e => {
        e.preventDefault()
        onClick()
      }}
    >
      {children}
    </a>
  )
}

// ...
export default connect(mapState, mapDispatch)(Link)
10
Sagiv b.g

mapStateToProps wird aufgerufen, wenn sich Daten ändern. Das zurückgegebene Objekt wird als neue Requisiten für die Komponente übergeben. Dies hat keinen Einfluss auf den Status der Komponente. Wenn Sie einen neuen Status festlegen möchten, nachdem die Komponente ihre neuen Requisiten erhalten hat, müssen Sie eine andere Lebenszyklusmethode verwenden: static getDerivedStateFromProps (in früheren Versionen von reag componentWillRecieveProps). Das von static getDerivedStateFromProps zurückgegebene Objekt ist Ihr neuer Status.

https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class

connect() verbindet Ihre Komponente mit dem Redux-Store. Ohne die Verbindungsfunktion (natürlich) wird Ihre mapStateToProps nicht funktionieren.

Ich bin mir nicht sicher, warum die API von rea-redux 'mapStateToProps' genannt wurde.

Wir reden über den Zustand des Ladens :)

2
messerbill

Das übergeordnete Ziel besteht darin, die Statusverwaltung von Redux nahtlos in die React-Anwendung zu integrieren. Redux dreht sich um den Store, in dem der gesamte Staat existiert. Es gibt keine Möglichkeit, den Store direkt zu ändern, außer durch Reduzierungen, die Aktionen von Aktionserstellern erhalten. Dazu muss der Aktionsersteller eine Aktion auslösen.

Die Funktion connect() verbindet unsere Komponenten direkt mit dem Redux-Store, indem der Status im Redux-Store übernommen und in eine prop abgebildet wird.

Dies ist die Kraft von Redux und deshalb benutzen wir sie.

Nehmen wir an, Sie bauen eine Komponente mit dem Namen LaundryList und möchten, dass eine Wäscheliste gerendert wird. Nachdem Sie die Provider in Ihrer "übergeordneten" Komponente verkabelt haben, füge ich sie in Anführungszeichen ein, da Provider technisch eine Komponente ist, also die übergeordnete Komponente wird.

Anschließend können Sie die Funktion connect() aus react-redux importieren und mapStateToProps übergeben, um diese Wäscheliste aus dem Redux-Store in Ihre LaundryList-Komponente zu laden.

Jetzt, da Sie Ihre Liste von Leinen in der LaundryList-Komponente haben, können Sie sich darauf konzentrieren, eine Liste von Elementen daraus zu erstellen:

class LaundryList extends Component {
  render() {
    console.log(this.props.linens);
    return <div>LaundryList</div>;
  }
}

Das enthält die Liste der Leinenobjekte, und für jede Liste von Leinen darin werden wir ein Jsx zurückgeben, das dieses Leinen auf meiner Liste darstellen wird.

Zurück in meiner Wäschelistenkomponente füge ich in der Wäschelistenkomponente eine Hilfsmethode hinzu, die so genannt wird:

class LaundryList extends Component {
  renderList() {

  }

  render() {
    return <div>LaundryList</div>;
  }
}

Daher besteht dieser Zweck dieser Hilfsmethode darin, die Liste der Leinen zu übernehmen, eine Karte darüber zu ziehen und einen großen Klecks von Jsx zurückzugeben, wie es so ist:

class LaundryList extends Component {
  renderList() {
    return this.props.linens.map((linen) => {
       return (

       );
    });
  }

  render() {
    return <div>LaundryList</div>;
  }
}
0
Daniel