A választó egy olyan függvény, amely az állapotból egy adott adatot olvas (származtat). A memorizálás gyorsítótárazza a választó eredményét, így csak akkor számítja újra, ha a bemeneti értékei megváltoznak — fontos a teljesítmény szempontjából, amikor a választók költséges munkát végeznek, vagy a szükségtelen újra-renderelés elkerülésére.
Alapvető választók — az állapot-hozzáférés beágyazása
// a selector knows HOW to pull a value out of the state shape
const selectUser = state => state.user;
const selectCartItems = state => state.cart.items;
const selectCartTotal = state =>
state.cart.items.reduce((sum, i) => sum + i.price, 0); // derived
A választók központosítják az állapot szerkezetéről szerzett tudást — az összetevők a selectCartTotal(state) értéket kérik, anélkül hogy tudnák, hol/hogyan tárolódik, ezért ha az állapot alakja megváltozik, csak egy választót frissítész, nem minden összetevőt.
A probléma: a származtatott választók minden híváskor újra számítanak
const selectExpensiveList = state =>
state.items.filter(i => i.active).sort(compareFn); // runs EVERY time, even if items didn't change
Az új tömböt/objektumot létrehozó választó minden híváskor egy új referenciát ad vissza — amely szükségtelen újra-renderelést (a React egy "új" értéket lát) és pazarlást okozhat.
A megoldás: memorizált választók (Reselect)
import { createSelector } from "reselect"; // or RTK's createSelector
const selectActiveSorted = createSelector(
[state => state.items], // input selector(s)
(items) => items.filter(i => i.active).sort(compareFn) // recompute ONLY if items changed
);
A createSelector gyorsítótárazza az eredményt, és csak akkor futtatja újra a költséges számítást, ha a bemeneti értékei (state.items) ténylegesen megváltoznak — ellenkező esetben az ugyanazt a referenciát adja vissza, megelőzve az újra-számítást és az alsóbb szintű újra-renderelést.
Választók összeállítása
const selectTotal = createSelector(
[selectActiveSorted, selectTaxRate], // build on other selectors
(items, rate) => items.reduce((s, i) => s + i.price, 0) * (1 + rate)
);
A választók összeállnak, összetett származtatásokat építenek fel egyszerű, egyedileg memorizált részekből.
Miért fontos
A választók leválasztják az összetevőket az állapot alakjáról (egy karbantartási győzelem) és biztosítanak egy helyet a származtatott adatok kifejeزésére.
A memorizálás hatékonnyá teszi a származtatott választókat — elkerülve az ismételt költséges számítást, és lényegesen, stabil referenciákat visszaadva, így a csatlakoztatott összetevők nem renderelonek újra szükségtelenül.
A Redux/NgRx alkalmazásokban a memorizált választók (Reselect/createSelector) a teljesítmény és az architektúra kulcsfontosságú eszköze; ugyanez a memorizálási ötlet a useMemo és computed formájában másutt jelenik meg.
