Atribut key: nejlevnější reset stavu v Reactu
key nepatří jen do seznamů. Když ho změníte, React komponentu zahodí a vytvoří novou — včetně veškerého stavu. Žádný useEffect není potřeba.
Znáte tenhle vzor? Komponenta s formulářem dostane nové userId a vy v useEffect ručně resetujete stav:
function ProfileEditor({ userId }: { userId: string }) {
const [draft, setDraft] = useState("");
useEffect(() => {
setDraft(""); // ❌ extra render a krátké probliknutí starých dat
}, [userId]);
// …
}Funguje to, ale komponenta se nejdřív vyrenderuje se starým stavem a teprve potom s novým. A s každým dalším kusem stavu přibývá řádek v efektu.
Řešení: key
<ProfileEditor key={userId} userId={userId} />React identifikuje komponenty podle typu a pozice ve stromu. key je součást té identity. Když se změní, React starou instanci odmountuje a připojí novou — se zbrusu novým stavem, refy i efekty. Uvnitř ProfileEditor pak žádný reset nepotřebujete.
Klíče v seznamech
Ze stejného důvodu nepoužívejte jako key index pole, pokud se položky mohou přesouvat, mazat nebo přidávat jinam než na konec:
// ❌ po smazání první položky se stav inputů „posune“
{todos.map((todo, i) => <TodoRow key={i} todo={todo} />)}
// ✅ stabilní identita
{todos.map((todo) => <TodoRow key={todo.id} todo={todo} />)}S indexem si React myslí, že řádek č. 0 je pořád ten samý řádek — jen s jinými props. Lokální stav (rozepsaný text, otevřené menu) tak zůstane u špatné položky.
Kdy key nestačí
Pokud chcete resetovat jen část stavu, nebo potřebujete zachovat něco drahého (třeba načtené obrázky), je lepší stav odvodit přímo při renderu nebo ho vytáhnout výš. Ale v osmi případech z deseti je key nejjednodušší a nejčitelnější řešení.