2016-10-13 1 views
5

Ich bin ein Neuling in React Native. Ich benutze Redux Architektur für meine reagieren native App, aber ich bin mit einem Problem aufgrund globalen Speicherzustand von Redux konfrontiert.React Native - Redux: Mehrere Instanzen desselben Status in App

Angenommen, zum Beispiel Während vorwärts in der App gehe ich wie folgt navigieren. enter image description here

Während zurück navigierenden,

enter image description here

Nach redux Architektur, es ändert den Zustand jeder Instanz der Seite in dem Navigationsstapel mit dem neuesten Stand in der Geschäft.

Hier ist der Code für das obige Beispiel ist,

Page.js [Komponente]

class Page extends Component{ 

    componentWillMount(){ 

    } 

    render(){ 
     var {image,apiCall} = this.props; 

     return (
     <View> 
      <Image Source={{uri:image}} style={{// style for the image}}> 
     </View> 
    )} 

    componentDidMount(){ 
     this.props.apiCall(this.props.route.data.link); // this.props.route.data.link -> this is just a link for             // the apiCall 
    } 

    componentWillReceiveProps(){ 

    } 

    shouldComponentUpdate(nextProps, nextState){ 
     if(this.props.image==nextProps.image){ 
      return false; 
     } 
     return true; 
    } 

    componentWillUpdate(){ 

    } 

    componentDidUpdate(){ 

    } 

    componentWillUnmount(){ 

    } 
} 

    const mapStateToProps = (state) => { 
    return { 
    image: state.PageDataReducer.image 
    }; 
    }; 

    const mapDispatchToProps = (dispatch) => { 
    return { 
     apiCall: (link) => { 
     dispatch(fetchProduct(link)); // fetchProduct() -> is a function which fetches the product from the         // network and dispatches the action. 
     }, 
    }; 
    }; 

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

fetchProduct() [Ein Funktionsprodukt holen]

export function fetchProduct(link) { 
    return function(dispatch){ 
    // fetches the product over network 
    dispatch(fetchedProduct(productLink)); 
    } 
} 

abgerufen Artikel [Action]

export const fetchedProduct = (productLink) => { 
    return { 
    type: FETCHED_PRODUCT, 
    image: image 
    }; 
}; 

PageDataReducer [Reducer]

export default function PageDataReducer(state = initialState, action) { 

    switch (action.type) { 

    case FETCHED_PRODUCT: 
    var newState = { 
     ...state, 
     image: action.image 
    }; 
     return newState; 

    default: 
     return state; 
    } 
} 

Meine Beobachtung: Immer dann, wenn gleiche Seite in der Navigation auftritt, und der Zustand, in dem Laden dieser Seite wird dann ändern ruft mapStateToProps() dieser Seite auf, wie oft sich die Seite im Navigationsstapel befindet. Und daher wiederholt es die Lebenszyklusmethoden dieser Seite, um den Status entsprechend dem letzten Status zu ändern.
In diesem Beispiel, wenn ich Klick auf der Banane in der Schublade, es ändert den Zustand von Mango Banane in dem Laden und mapStateToProps() 3-mal aufgerufen wird (weil die Seite 3 mal vorhanden ist in der Navigation Stapel) und damit alle Lifecycle-Methoden der Reaktion von ComponentWillReceiveProps() auf ComponentDidUpdate() wird 3 Mal aufgerufen, nur um den Zustand dieser Seite gemäß dem neuesten Stand zu ändern.

Was ich will: Ich möchte den unterschiedlichen Zustand der Seite in der Navigation, So dass während ich zurück gehe kann ich alle verschiedenen Produkte sehen, die ich besucht habe.

Das Problem ist offensichtlich nach Redux-Architektur, aber ich bekomme nicht den Trick, es zu lösen. Jede Hilfe oder jede andere Arbeit um mein Ziel zu erreichen würde sehr geschätzt werden.

+0

Können Sie Ihre Frage klären? –

+0

@DamenLeroux, ja Ich habe meine Frage oben bearbeitet. Kannst du es bitte noch einmal durchgehen? –

+0

Sie haben gesagt: "Gemäß der Redux-Architektur ändert sich der Status jeder Instanz der im Navigationsstapel vorhandenen Seite mit dem neuesten Stand im Geschäft." Die redux-Architektur macht das nicht ohne Code, um jeden App-Status irgendwo zu speichern. Vielleicht ist es hier dein Problem –

Antwort

-1

Was Sie versuchen, kann nicht nur mit Redux gemacht werden.

Sie müssen im Browser oder in der App Ihre Änderungen als Navigation historisieren. HistoryJS wird dazu verwendet. Dieses Modul wird von react-router verwendet, um eine gute UX in der Webnavigation zu bieten.

Verwenden Sie also entweder react-router, um verschiedene Seiten zu deklarieren (eine für jede Frucht) oder verwenden Sie mindestens HistoryJS, um den Navigationsstatus programmatisch zu speichern.

Ich weiß nicht, wie react-router reagiert auf native Anwendungen, also schauen Sie sich React Native Router. Es bietet einen Weg zu handle navigation with Redux on native app.

+0

Ja, tatsächlich habe ich versucht mit [** react-native-router-flux **] (https://github.com/aksonov/react-native-router-flux) -Bibliothek und sogar mit reagiere nativ ** experimentelle ** Navigationskomponente. Aber hat nicht funktioniert. Das Problem liegt an der Redux-Architektur. Wenn ich es mit normalem Zustand (nicht mit Redux) mache, funktioniert es natürlich richtig. Aber ist es gut, den Status für einige Komponenten und Redux für einige zu verwenden? und wenn ja, kann der Zustand verschiedener Komponenten in der gesamten App verwaltet werden? –

+0

Es gibt keine Regeln für die Verwendung des einen oder anderen. Je nach dem, was Sie tun möchten, können Sie sowohl Redux- als auch Komponentenzustände verwenden. Ein Komponentenstatus muss in der gesamten App nicht verwaltet werden können. –

1

Sie sollten den Speicher Ihrer Domaindaten, z. B. Daten über Apple, Mango und Banane, vom Speicher Ihres UI-Status entkoppeln, z. B. welches Element gerade ausgewählt ist. Im Domain-Datenteil würden Sie alle Elemente speichern, die einmal geladen wurden (möglicherweise möchten Sie später einige Garbage-Collection-Richtlinien hinzufügen, z. B. zuletzt verwendete Listen, um Speicherplatz zu sparen).

Die Ansichtskomponenten würden sich dann mit beiden Teilen des App-Statusbaums verbinden: mit dem UI-Teil, um den aktuell ausgewählten Teil zu erhalten, und mit dem Teil der Domäne, um Details zum ausgewählten Gegenstand zu erhalten.

In Ihrer Funktion mapStateToProps wird zuerst die aktuelle Auswahl extrahiert, dies muss ein Bezeichner sein. Sie können es auch von woanders extrahieren, z. von der Komponente Requisiten (das zweite Argument zu mapStateToProps). Dann verwenden Sie diesen extrahierten Bezeichner, um die bereits geladenen Daten aus dem Domain-Datenspeicher abzurufen. Wenn sich die ausgewählten Daten nicht im Speicher befinden (z. B. wenn der Benutzer die Seite zum ersten Mal besucht oder wenn bereits eine Müllsammlung stattgefunden hat), setzen Sie einen leeren Wert in Requisiten, was bedeutet, dass componentDidMount oder componentWillReceiveProps Hooks sind dass sie eine Datenladeanforderung stellen müssen (sie kann als eine Ausgabe einer Aktion implementiert werden, die die Datenanforderung an eine Saga oder einen Thunk signalisiert, abhängig davon, was Sie zum Verwalten des Datenladens verwenden), während dies geschieht, würde das Rendern erfolgen gib einen "loading ..." Stub zurück. Wenn die Anforderung abgeschlossen ist, aktualisiert ein anderer Dispatch die Aktualisierung des Domänendatenspeichers, wodurch die Verbindung hergestellt wird, um einen weiteren mappStateToProps-Aufruf auszuführen. Dies würde dazu führen, dass die ausgewählten Daten bereits im Speicher vorhanden sind, sodass keine neue Datenladeanforderung erfolgt , und der Renderer wird genügend Daten für die Anzeige haben.

Verwandte Themen