2016-11-28 4 views
2

Ich möchte Funktionen haben, die den aktuellen Zustand erhalten können, um einige Logik damit zu tun, ohne den aktuellen Zustand über Parameter an die Funktion übergeben zu müssen.GETTERS in Redux-Aktionen - React Native

Hier ist mein Beispiel.

In meiner Aktion Datei, die ich habe:

export const addToSearchHistory = (newSearch) => ({type: ADD_TO_SEARCH_HISTORY, newSearch}) 
export const addToCardHistory = (newCard) => ({type: ADD_TO_CARD_HISTORY, newCard}) 

Und zum Beispiel würde Ich mag einen „Getter“ Funktion haben, der mir sagt, wenn die „Geschichte Suchen“ 10 Artikel getroffen hat. Also, was ich tat, ist:

export const searchHasMaxHistory =() => (dispatch, getState) => { 
    var state = getState() 
     search = state.search 

    return search.history == 10 ? true : false 
} 

Und ich binden Sie diese Funktion mit den anderen „echten“ Aktionen mit bindActionCreators:

const mapDispatchToProps = (dispatch) => { 
    return bindActionCreators({ 
    addToSearchHistory, 
    addToCardHistory, 

    searchHasMaxHistory 
    }, dispatch) 
} 

Also werde ich wie alle normalen Aktionen zugänglich sein. Es funktioniert gut und macht genau das, was ich will.

Aber die wirkliche Frage ist, ist es Anti-Muster, um es wie eine Aktion zu binden, aber es gibt keine Aktion zurück? Darf ich damit auf Probleme stoßen? Und gibt es dafür eine "richtige" Lösung?

+0

mapDispatchToProps umschließt Ihre Funktionen in Dispatch-Aufrufen. Wenn Ihr Aktionsersteller (searchHasMaxHistory) "search.history == 10? True: false" zurückgibt, wird dieser Rückgabewert ausgelöst. Versand ist nur dazu bestimmt, eine Aktion (einfaches Objekt) zu versenden, die den Status Ihrer Anwendung ändert. In diesem Fall wird es nicht, weil keiner Ihrer Reduzierer eine Aktion behandelt: bool (true/false) –

Antwort

2

Dazu sollten Sie Ihren "Getter" (der in the docs als "Selektor" bezeichnet wird) über die Funktion mapStateToProps an Ihre Komponente binden.

// the selector (probably in your reducer file) 

export const searchHasMaxHistory = state => { 
    return state.search.history == 10 ? true : false 
} 

// in your component 

const mapStateToProps = (state) => { 
    return { 
    hasHitMaxHistory: searchHasMaxHistory(state) 
    } 
} 

const mapDispatchToProps = ... // keep the same, remove your "getter" 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(YourComponent) 

Dieser Ansatz macht mehr Sinn für mich, als Bestandteil der neuen Stütze verhält wie beabsichtigt, und lösen ein(), wenn die zurückgegebenen Wertänderungen machen.

+0

Ja, ich hörte von den "Selektoren", aber es wird nicht aktualisiert, wenn sich der Zustand ändert. Es scheint, dass es sollte:/ – Leon

+0

Lol mein Schlechter hat es nicht aktualisiert, weil ich andere Änderungen vorgenommen habe und es nicht mehr "verlinkt" wurde ... Danke! Ihre Antwort schien die beste zu sein, weil Sie über Selektoren gesprochen haben und das ist der richtige Weg, wenn Sie Getter-ähnliche Funktionen mit Redux haben wollen :) – Leon

+0

Gern geschehen! Dieser Teil von react-redux ist die eine Sache, die sich manchmal etwas zu magisch anfühlt. – vgrafe

1

Ich sehe, dass Sie Ziel ist:

Ich mag würde Funktionen haben, die den aktuellen Zustand gewisse Logik damit zu tun bekommen können, ohne den aktuellen Zustand über Parameter an die Funktion passieren zu müssen .

Aber bindActionCreators(actionCreators, dispatch) ist für einen anderen Zweck.

Sie wickelt alle You-Actions-Ersteller mit einem dispatch-Aufruf ein, sodass sie direkt aufgerufen werden können.

Wir machen Dinge auf eine hackische Weise, stattdessen verwenden wir das ursprüngliche Objekt store, um den Zustand zu erhalten.

Erstellen Sie einen Getter für Ihre store Objekt, wo Sie createStore.

import { createStore } from 'redux' 
import reducer from './reducer'; 

let store = {}; 

export default function storeCreator() { 
    // ...do things 

    store = createStore(reducer); 

    // ...do more things 

    return store; 
} 

export function getStore() { 
    return store; 
} 

Jetzt in Ihrem state-Getter:

import { getStore } from './storeCreator'; 

export function searchHasMaxHistory() { 
    const store = getStore(); 
    const state = store.getState(); 
    const search = state.search; 

    return search.history == 10 ? true : false 
} 
+1

Nun, das ist ein Anti-Muster. Sie erstellen ein Store-Singleton. Wenn Sie einen Shop mehr als einmal erstellen (nicht, dass Sie das möchten), überschreiben Sie Ihre "Store" -Variable und getStore() wird Ihnen immer den neuesten Singleton geben. In diesem Fall benötigen Sie weder storeCreator() noch getStore(). Schreiben Sie einfach "export default createStore (Reducer)" und jeder "Import" gibt Ihnen die gleiche Filialinstanz. –

2

Werfen Sie einen Blick auf die docs von connect()

mapStateToProps (state): (Funktion): Wenn angegeben, die Komponente wird Redux Store Updates abonnieren. Jedes Mal, es aktualisiert, mapStateToProps wird

genannt So könnten Sie Ihre connect() Klausel wie folgt schreiben:

function mapStateToProps(state) { 
    return { 
    searchHasMaxHistory: state.search.history === 10 
    }; 
} 
connect(mapStateToProps)(YourComponent) 

Aber natürlich, das wäre Ihr neuer Wert auf jedem Geschäft Änderung zu berechnen. Das willst du vielleicht nicht. In diesem Fall könnten Sie eine separate Funktion definieren und Ihren Status bei jeder Änderung des Speichers (Status) an diesen binden.

function isMaxHistoryReached(state) { 
    return state.search.history === 10; 
} 

function mapStateToProps(state) { 
    return { 
    searchHasMaxHistory: isMaxHistoryReached.bind(YourComponent, state) 
    }; 
} 
connect(mapStateToProps)(YourComponent) 

Nun erstellt das noch eine neue Funktion im Speicher bei jeder Statusänderung, aber es wird es nicht aufrufen.