Odvozený stav je jakákoli hodnota, kterou si můžete vypočítat ze stávajícího stavu místo aby jste ji ukládali zvlášť. Princip: pokud si to umíte spočítat, neukládejte to — odvoďte to při každém vykreslení. Ukládání odvozitelných hodnot je pozvání do problémů se synchronizací.
Antipattern: ukládání toho, co si umíte spočítat
// ❌ storing a derived value as separate state
function Cart() {
const [items, setItems] = useState([]);
const [total, setTotal] = useState(0); // DUPLICATE — derivable from items
function addItem(item) {
setItems([...items, item]);
setTotal(total + item.price); // must remember to update total too — easy to forget 🐛
}
}
Nyní je total druhá kopie informací, která je již v items. Každá změna v items také musí aktualizovat total, a v okamžiku, kdy jednu vynecháte (odebrání, změna množství), si nebudou odpovídat a UI zobrazí chybný součet.
Řešení: odvoďte to při vykreslení
// ✅ compute total from items — always correct, never out of sync
function Cart() {
const [items, setItems] = useState([]);
const total = items.reduce((sum, i) => sum + i.price, 0); // derived each render
function addItem(item) {
setItems([...items, item]); // ONE update; total recomputes automatically
}
}
S odvozením total není nic navíc, co by bylo třeba držet v synchronizaci — změňte items a součet bude vždy správný.
Memoizujte pouze pokud je výpočet drahý
const sortedFiltered = useMemo(
() => items.filter(i => i.active).sort(compareFn), // expensive derivation
[items] // recompute only when items change
);
Pro těžké odvozené hodnoty (rozsáhlé filtry/řazení) useMemo/computed/selectors cache výsledek tak, aby se přepočítalo pouze když se změní závislosti — ale je to stále odvozené, ne uložené jako nezávislý stav.
Běžné odvozené hodnoty
Totals/counts, filtered or sorted lists, fullName from first+last,
isValid from form fields, formatted/displayed strings, "is everything selected?"
Proč na tom záleží
Neduplikování odvozeného stavu je přímou aplikací principu jediného zdroje pravdy — eliminuje celou třídu chyb, kde se kopie rozejdou.
Pravidlo "odvoďte, neukládejte" udržuje váš stav minimální a vaše UI konzistentní podle konstrukce.
Poznávání toho, co je odvozitelné (a sáhání na useMemo/computed/selectors pouze z hlediska výkonu, nikdy pro vytvoření druhého zdroje pravdy) je charakteristikou čistého, odolného proti chybám návrhu stavu.
