2017-11-07 4 views
3

Ich habe einen normalen Wähler, die gerade verwendet wird, Teil des Staates zu bekommen:Erneut auswählen - macht es Sinn, einen gespeicherten Selektor zu erstellen, der nur dazu verwendet wird, einen Teil des Zustands zu erhalten?

export const getAllPosts = state => { 
    return state.posts; 
}; 

Wenn ich die Neuauswahl verwenden, um die Wähler zu wickeln:

import { createSelector } from 'reselect'; 

export const allPosts = createSelector(
    getAllPosts, 
    (posts) => posts 
); 

Macht es Sinn machen, wie die Verbesserung der Leistung? Meiner Meinung nach ist der Wrapper nicht notwendig.

+0

Große Frage - ich konnte das nirgendwo angesprochen finden. –

Antwort

1

Nein, es macht keinen Sinn, zu schaffen ein Memo-Selektor, um nur einen Teil des Statusbaums zu erhalten.

Der Grund ist, dass connect wird es eigene flache Gleichheitsprüfung für jede Requisite von mapStateToProps übergeben. Wenn die vom Selektor zurückgegebene Prop diese flache Überprüfung der Gleichheit zusammen mit den anderen Requisiten übergibt, wird render nicht unnötig aufgerufen. Wenn der Selektor einfach einen Teil des Zustandsbaums zurückgibt und dieser Teil des Zustandsbaums nicht modifiziert wurde, ist eine oberflächliche Überprüfung der Gleichheit ausreichend. Wenn der Selektor jedoch anhand der Ergebnisse anderer Selektoren berechnet wird, ist die Verwendung von createSelector eine gute Wahl. Erstens bietet es eine schöne Syntax zum Erstellen von Selektoren. Zweitens, wenn die Berechnung des Kombinierens der Selektoren potentiell teuer ist, werden Sie einen Leistungsvorteil erhalten. Drittens, wenn der Selektor ein neues, aber gleichwertiges Objekt oder Array zurückgeben würde, wäre die Überprüfung der flachen Gleichheit, die von connect bereitgestellt wird, nicht ausreichend. In diesem Fall würde die Memoisierung, die createSelector bereitstellt, sicherstellen, dass dasselbe Objekt oder dieselbe Array-Instanz zurückgegeben wird, wenn sich die Eingaben nicht geändert haben und dann die oberflächliche Überprüfung der Gleichheit ausreicht, um kostspielige erneute Rendervorgänge zu vermeiden.

Also nur für das Freilegen von Teilen des Zustandsbaums createSelector fügt nichts hinzu.

Für fast alle Selektoren, die aus mehreren Teilen des Statusbaums createSelector berechnet werden, beginnt der Wert zu erhöhen. Die Höhe des Werts, die hinzugefügt wird, hängt vom Selektor ab, da er einfacher zu lesen ist, um sicherzustellen, dass Sie den Komponentenbaum nicht unnötig rendern.

0

Nein, das bietet keinen wirklichen Vorteil.

Was ich gefunden habe, ist, dass mein erster Ebene Selektoren sind einfach schlicht Funktionen und alle Wähler, die diese Notwendigkeit tiefer als memoized werden:

// assume state is: {first : {second {} } } 

const selectFirst = state => state.first; 

const selectSecond = createSelector(
    selectFirst, 
    first => first.second 
); 
+0

Warum SelectSecond sollte gespeichert werden? Ich kann keine offensichtliche Leistungsverbesserung sehen. Könnten Sie mehr Erklärung geben? –

+0

Dieses Beispiel war ziemlich trivial. Aber stellen Sie sich vor, dass der Ausgabe-Selektor für 'selectSecond()' einige teure Arbeit verrichtet (vielleicht sortiert/filtert er ein Array), und wir wollen das nur tun, wenn sich das Array geändert hat. Die Verwendung von createSelector() und das Memoisieren der Eingaben stellen sicher, dass der Ausgabeselektor nur ausgeführt wird, wenn sich die Eingaben geändert haben. – markerikson

0

In Ihrem Fall macht es keinen Sinn, weil Sie nur die gleiche Referenz aus dem Geschäft zurückgeben, die immer flach ist sich selbst (oder seinen vorherigen Zustand), es sei denn, Sie ändern es.

Wenn Sie ein anderes Szenario zum Beispiel ein Szenario vorstellen, wo Sie Ihre Einheiten in einem Objekt anstelle eines Arrays im Speicher, aber Sie möchten ein Array zu Ihrer Komponente zurückzukehren, dann müssen Sie leiten Daten:

export const selectAllPosts = createSelector(
    getAllPostsFromStore, // returns { 1: {...}, 2: {...} } 
    (allPosts) => Object.keys(allPosts).map(key => allPosts[key]) 
); 

Jetzt wurde Ihr Selektor zu einem Leistungsschub, da er nur die abgeleiteten Daten berechnet, wenn sich etwas im Geschäft ändert.

Meine Faustregel lautet also: Wenn Sie keine Daten ableiten, müssen Sie sie nicht memotisieren.

Verwandte Themen