Junior
Jak správně měnit stav komponent v Reactu?
sobes.tech AI
Odpověď od AI
Změna stavu v React probíhá přes metodu setState pro třídyové komponenty nebo pomocí hooku useState pro funkcionální komponenty.
Třídyové komponenty:
// Import React
import React, { Component } from 'react';
// Vytvoření třídy komponenty
class MyComponent extends Component {
// Inicializace stavu
constructor(props) {
super(props);
this.state = {
count: 0
};
}
// Metoda pro změnu stavu
incrementCount = () => {
// Použití setState
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Čítač: {this.state.count}</p>
<button onClick={this.incrementCount}>Zvýšit</button>
</div>
);
}
}
// Export komponenty
export default MyComponent;
setStateje asynchronní.setStateslučuje nový stav s aktuálním (shallow merge).setStatemůže přijmout funkci, která vrací nový stav na základě předchozího:
// Metoda pro změnu stavu s použitím funkce
incrementCountFunction = () => {
this.setState((prevState) => ({
count: prevState.count + 1
}));
};
Funkcionální komponenty (s useState):
// Import React a useState
import React, { useState } from 'react';
// Vytvoření funkcionální komponenty
function MyFunctionComponent() {
// Inicializace stavu s useState
const [count, setCount] = useState(0); // [aktuální stav, funkce pro aktualizaci]
// Funkce pro změnu stavu
const incrementCount = () => {
// Použití funkce pro aktualizaci
setCount(count + 1);
};
return (
<div>
<p>Čítač: {count}</p>
<button onClick={incrementCount}>Zvýšit</button>
</div>
);
}
// Export komponenty
export default MyFunctionComponent;
useStatevrací pole se dvěma prvky: aktuálním stavem a funkcí pro jeho aktualizaci.- Funkce pro aktualizaci, kterou
useStatevrací, nahrazuje aktuální stav, nikoliv jej slučuje. - Pokud je potřeba, lze předat funkci do funkce aktualizace, pokud nový stav závisí na předchozím:
// Funkce pro změnu stavu s použitím funkce
const incrementCountFunction = () => {
setCount(prevCount => prevCount + 1);
};
Důležité body při změně stavu:
- Nekonfigurujte stav přímo: Nikdy nepřiřazujte novou hodnotu vlastnosti
statepřímo (napříkladthis.state.count = 5nebocount = 5). React si tuto změnu nevšimne a komponenta se nepřerenderuje. - Úprava objektů a polí: Při změně objektů nebo polí ve stavu vždy vytvářejte jejich nové kopie. React porovnává odkazy a pokud odkaz zůstává stejný, předpokládá, že data se nezměnila, a nevolá přerenderování.
// Změna objektu v třídní komponentě
this.setState(prevState => ({
user: {
...prevState.user, // Kopírujeme staré vlastnosti
name: 'Nové jméno' // Aktualizujeme požadovanou vlastnost
}
}));
// Změna pole v funkcionální komponentě
setItems(prevItems => [...prevItems, 'Nový prvek']); // Přidání nového prvku
- Asynchronnost
setState: Pokud potřebujete provést akci po aktualizaci stavu a přerenderování komponenty, použijte druhý argumentsetState(callback) nebo hookuseEffectve funkcionálních komponentách.
// Callback v `setState`
this.setState({ count: this.state.count + 1 }, () => {
console.log('Stav byl aktualizován!');
});
// `useEffect` pro reakci na změnu stavu
useEffect(() => {
console.log('Stav count se změnil:', count);
}, [count]); // Závislost: hook se spustí při změně count
Porovnání metod:
| Charakteristika | Třída (setState) |
Funkční (useState) |
|---|---|---|
| Syntaxe | Metoda this.setState(newState[, callback]) |
Hook const [state, setState] = useState(initialState) |
| Sloučení/Výměna | Sloučí nový stav s aktuálním (shallow merge) | Nahradí aktuální stav novým |
| Asynchronní | Je asynchronní | Je asynchronní při volání z handlerů, ale synchronní v render fázi Reactu |
| Závislost na předchozím stavu | Přeneste funkci do setState: this.setState(prevState => ({...})) |
Přeneste funkci do setState(prev => ({...})) |