action je prostý objekt popisující co se stalo; reducer je čistá funkce, která vezme aktuální stav a akci a vrátí další stav. Společně implementují předvídatelné přechody stavu.
Actions — popisují události
{ : , : { : , : } }
{ : , : }
action je prostý objekt popisující co se stalo; reducer je čistá funkce, která vezme aktuální stav a akci a vrátí další stav. Společně implementují předvídatelné přechody stavu.
{ : , : { : , : } }
{ : , : }
Actions neděláme nic — jsou deklarativní popisy událostí. Jejich pojmenování v minulém čase ("přidáno", "přepnuto") odráží, že zaznamenávají, co se stalo.
function todosReducer(state = [], action) {
switch (action.type) {
case "todos/added":
return [...state, action.payload]; // new array
case "todos/toggled":
return state.map(t => // new array, new object for the changed one
t.id === action.payload ? { ...t, done: !t.done } : t
);
default:
return state; // unknown action → unchanged
}
}
Signatura reduceru je (state, action) => newState. Musí vrátit nový objekt/pole stavu (immutabilně), nikdy neměnit vstup.
Čistá funkce: (1) vrací stejný výstup pro stejný vstup a (2) má žádné vedlejší účinky. Reducers musí dodržovat obě pravidla:
// ❌ NOT pure — breaks everything
function badReducer(state, action) {
state.value++; // ❌ mutates input (breaks change detection, time-travel)
fetch("/api/log"); // ❌ side effect (non-deterministic, untestable)
return { value: Math.random() }; // ❌ non-deterministic output
}
Čistota umožňuje podpisové funkce Redux:
✓ Predictability — same state + action ALWAYS gives the same result
✓ Time-travel / replay — you can re-run actions to reproduce any state
✓ Testability — just call reducer(state, action) and assert; no mocks needed
✓ Change detection — returning new references lets the UI detect changes
Vedlejší účinky (volání API, logování, náhodnost) patří do middleware (thunks/sagas) nebo effects — nikdy ne do reducerů.
Model action/reducer je jádrem správy stavu ve stylu Redux a důvod, proč je tak snadno laditelný a testovatelný.
Požadavek čistoty není svévolný: to je to, co umožňuje time-travel debugging, replay akcí a triviální testování jednotek, a to je důvod, proč musí vedlejší účinky žít jinde.
Tento vzor řízený čistou funkcí a neměnný update se opakuje v Redux, NgRx, useReducer a dále — jeho pochopení (a disciplína udržování čistoty reducerů) je zásadní pro předvídatelný stav.