in den Fällen, Sie in Ihrer Frage angegeben haben Reselect
nicht wirklich einen beliebigen Wert hinzufügen.
Der Grund dafür ist, dass connect
von react-redux
bereitgestellt wird es tut eigene seicht ist die in Ihrer mapStateToProps
Funktion versehen Requisiten vergleichen, um zu bestimmen, ob ein erforderlich machen. In den von Ihnen bereitgestellten Beispielen, wenn sich die Werte day
, minDate
oder maxDate
nicht ändern, verschwenden Sie keine Zeit mit unnötigen Renderings.
Der reale Wert von Reselect
kommt in, wenn Ihr Selektor etwas zurückgibt, das berechnet wird.
Um ein Beispiel aus Vlad zu leihen. Reselect
ist für Selektoren so Ihre Selektoren Komponieren wie folgt aussehen:
const mapStateToProps = state => ({
isOutOfRange: getIsDateOutOfRange(state)
});
In diesem Fall Reselect
ist für eine nette Syntax bietet Selektoren kombiniert:
export const getDay = state => state.filters.day;
export const getMinDate = state => state.filters.minDate;
export const getMaxDate = state => state.filters.maxDate;
export const getIsDateOutOfRange = createSelector(
getDay,
getMinDate,
getMaxDate,
(day, minDate, maxDate) => day > maxDate || day < minDate
);
Und Ihre mapStateToProps
Funktion kann wie folgt aussehen und eine geringfügige Leistung profitiert von der Tatsache, dass getIsDateOutOfRange
nur neu berechnet wird, wenn einer der abhängigen Selektoren einen anderen Wert zurückgibt.
Und da liegt der versteckte Leistungsvorteil von Reselect
. Wenn Sie über einen Selektor verfügen, der ein berechnetes Array oder ein Objekt zurückgibt, werden zwei identische Werte, die vom Selektor zurückgegeben werden, keine flache Gleichheitsprüfung bestehen, die Reselect
oder connect
für Memozwecke verwendet.
[0, 1] === [0, 1] // false
Also für ein konstruiertes Beispiel:
export const getDays = state => state.filters.days;
export const getMinDate = state => state.filters.minDate;
export const getMaxDate = state => state.filters.maxDate;
export const getDaysWithinRangeNotPerformant = state => {
const days = getDays(state);
const minDate = getMinDate(state);
const maxDate = getMaxDate(state);
return days.filter(day => day > minDate && day < maxDate);
};
export const getDaysWithinRangePerformant = createSelector(
getDay,
getMinDate,
getMaxDate,
(days, minDate, maxDate) =>
days.filter(day => day > minDate && day < maxDate)
);
Der Performance-Vorteil, dass Reselect
hier entriegelt ist zweifach.
Erst bei mehreren Aufrufen an getDaysWithinRangePerformant
wird der möglicherweise teure filter
nur ausgeführt, wenn sich die aktuellen Parameter geändert haben.
Zweitens und am wichtigsten ist, getDaysWithinRangeNotPerformant
jedes Mal von connect
genannt wird, wird es ein neues Array zurück, was bedeutet, dass die flache in connect
die Stütze vergleichen wird falsch und render
wird wieder einmal aufgerufen werden, wenn die tatsächlichen Tage selbst haben nicht geändert. Weil getDaysWithinRangePerformant
durch createSelector
Memo ist, wird es genau die gleiche Array-Instanz zurückgeben, wenn sich die Werte nicht geändert haben und daher der flache Vergleich von Requisiten in connect
wahr ist und es in der Lage ist, eigene Optimierungen durchzuführen und unnötiges Rendering zu vermeiden.
Und das ist meiner Meinung nach der große Vorteil, Reselect
bietet.
AFAIK, erneut auswählen merkt sich auch den resultierenden Wert. Wenn Sie den Selektor an vielen Stellen verwenden, rufen Sie die Funktion nicht jedes Mal auf. –
Aber wie ist das anders als nur sich selbst auszuwählen? Ich bekomme es, wenn es darum geht, ein Array zu filtern, aber wenn es nicht ist? –
Und man könnte sagen, dass es sich vom Laden entkoppelt, aber wie macht es das, da es immer noch darauf ankommt, dass es einen Laden gibt, der ein Objekt namens filter hat und drinnen Tag, minDate und maxDate? –