2017-10-07 3 views
2

Ich lerne, wie Redox funktioniert, aber es ist eine Menge Code, um einfache Dinge zu tun. Ich möchte zum Beispiel einige Daten vom Server laden, bevor sie angezeigt werden. Aus Gründen der Bearbeitung kann ich nicht einfach nur eingehende Requisiten verwenden, sondern Requisiten-Daten in den lokalen Zustand kopieren.Rückrufe mit Redux-Thunk/Redux-Observable mit Redux

Soweit ich gelernt habe, muss ich eine Fetch_request Aktion senden. Bei Erfolg wird eine Aktion fetch_success den Store mit einem neuen Element aktualisieren. Das aktualisierte Element bewirkt, dass die Renderfunktion meiner Komponente aktualisiert wird.

In Komponente

componentWillMount() { 
    this.props.FETCH_REQUEST(this.props.match.params.id); 
} 
... 

In Aktionen

export function FETCH_REQUEST(id) { 
    api.get(...) 
    .then(d => FETCH_SUCCESS(d)) 
    .catch(e => FETCH_FAILURE(e)); 
} 
... 

In Minderer

export function FETCH_REDUCER(state = {}, action ={}) { 
    switch (action.type) { 
    case 'FETCH_SUCCESS': 
     return { ...state, [action.payload.id]: ...action.payload } 
    ... 
} 

Zurück in der Komponente

this.props.FETCH_REDUCER 
// extra code for state, getting desired item from... 

Kann ich stattdessen eine react-thunk-Funktion aufrufen und einige Callback-Funktionen übergeben? Das Thunk-Protokoll kann den Speicher aktualisieren, und Rückrufe können den lokalen Status der Komponente ändern.

In Komponente

componentWillMount() { 
    this.props.FETCH_REQUEST(this.props.match.params.id, this.cbSuccess, this.cbFailure); 
} 
cbSuccess(data) { 
    // do something 
} 
cbFailure(error) { 
    // do something 
} 
... 

In Aktion

export function FETCH_REQUEST(id, cbSuccess, cbFailure) { 
    api.get(...) 
    .then(d => { 
     cbSuccess(d); 
     FETCH_SUCCESS(d); 
    }).catch(e => { 
     cbFailure(d); 
     FETCH_FAILURE(e); 
    }); 
} 
... 

Ist das falsche? Kann ich dasselbe mit Redux-Observable tun?


UPDATE 1

zog ich fast alles auf die redux speichern, auch für Bearbeitungen (dh this.setState mit this.props.setState ersetzt). Es erleichtert das staatliche Management. Jedes Mal, wenn ein onChange-Befehl ausgelöst wird, wird jedoch ein neuer Status angezeigt. Kann jemand bestätigen, ob das in Ordnung ist? Ich mache mir Sorgen um die Speicherverwaltung der App, weil ich redigiere, um jeden Status zu referenzieren.

Antwort

1

Zuerst sollten Sie Ihre API in componentDidMount statt componentWillMount aufrufen. Mehr dazu unter: what is right way to do API call in react js?

Wenn Sie einen redux Store verwenden, Ihre Komponenten abonnieren Sie den Zustandsänderungen mit der mapStateToProps Funktion und sie ändern Zustand mit den Aktionen, Requisiten durch die mapDispatchToProps Funktion hinzugefügt (vorausgesetzt, Sie diese Funktionen verwenden in Ihrem Verbindung herstellen). Sie abonnieren also bereits Statusänderungen mit Ihren Requisiten. Die Verwendung eines Callbacks wäre ähnlich, wenn der Callback Ihnen eine Änderung mitteilt, von der Ihre Komponente aufgrund einer Änderung ihrer Requisiten bereits weiß. Und die Änderung der Requisiten würde ein erneutes Rendern der Komponente auslösen, um den neuen Zustand zu zeigen.

UPDATE: Der Fall, auf den Sie verweisen, eines Eingabefeldes, das bei Änderung jedes Zeichens ein onChange-Ereignis auslöst, kann viele Aktualisierungen des Geschäfts verursachen. Wie in meinen Kommentaren erwähnt, können Sie mit einem API wie _.debounce die Aktualisierungen des Speichers drosseln, um die Anzahl der Statusänderungen in solchen Fällen zu reduzieren. Mehr zur Handhabung bei Perform debounce in React.js.

Das Problem der Speicherverwaltung ist ein echtes Problem in realen Anwendungen, wenn Redux verwendet wird. Die Art und Weise die Wirkung der wiederholten Updates an den Staat zu reduzieren, ist zu

  1. die Form Zustand Normalisieren: http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
  2. memoized Selektoren erstellen mit Reselect (https://github.com/reactjs/reselect)
  3. die Beratung in den Artikel über die Leistung bereitgestellt Folgen in Redux github Seiten (https://github.com/reactjs/redux/blob/master/docs/faq/Performance.md)

Denken Sie auch daran, dass, obwohl der ganze Staat mutiert verhindern kopiert werden soll, nur die Scheibe Zustand, die aktualisiert werden muss, um Änderungen. Wenn Ihr Status beispielsweise 10 Objekte enthält und nur eines davon geändert wird, müssen Sie den Verweis des neuen Objekts im Status aktualisieren. Die verbleibenden 9 unveränderten Objekte verweisen jedoch immer noch auf die alten Referenzen und die Gesamtzahl der Objekte in Ihrem Speicher ist 11 und nicht 20 (ohne das umfassende Zustandsobjekt.)

+0

Wenn ich die Daten bearbeiten wollte, die ich von FETCH_REDUCER erhalten habe, würde meine Eingabe onChange nicht eine Aktion für jede Zeichenänderung senden müssen? Wäre das wegen des Klonens nicht speicherverschwendend? Meine Idee war, die Daten von FETCH_REDUCER in den lokalen Zustand zu kopieren, lokal Änderungen vorzunehmen und dann eine Aktion zum Aktualisieren des Geschäfts zu senden. – SILENT

+0

Ich stimme deinem Standpunkt zu. Und die akzeptierte Arbeit besteht darin, eine Funktion wie _.debounce zu verwenden, um den Aufruf von api von Ihrer onChange-Funktion zu drosseln. Etwas in der Art von @ juliens Antwort in https://stackoverflow.com/questions/23123138/perform-debounce-in-react-js – palsrealm