Licznik z błędem
Przeanalizuj poniższy przykład, a następnie go uruchom. Czy działa zgodnie z oczekiwaniem?
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const handleIncrement = () => {
// Błąd: oba wywołania używają starej wartości count
setCount(count + 1);
setCount(count + 1);
};
return (
<div style={{ padding: "20px" }}>
<h1>Błędne zwiększanie licznika</h1>
<p>Licznik: {count}</p>
<button onClick={handleIncrement}>Zwiększ dwa razy</button>
</div>
);
}
export default App;React grupuje wiele zmian stanu lub propsów w jednym renderze, zamiast renderować komponent osobno po każdej zmianie. Jeśli w jednej funkcji wywołasz setState kilka razy, React nie wykona tyle renderów, ile wywołań tylko zrobi tylko jeden render na koniec.
Poprawna wersja:
const handleIncrement = () => {
// Poprawnie: każda aktualizacja korzysta z aktualnej wartości
setCount(prev => prev + 1);
setCount(prev => prev + 1);
};Przykład z tablicą
import React, { useState } from "react";
function App() {
const [items, setItems] = useState([]);
const addItems = () => {
// Błąd: oba wywołania używają starej wartości items
setItems([...items, "A"]);
setItems([...items, "B"]);
};
return (
<div style={{ padding: "20px" }}>
<h1>Błędne dodawanie elementów</h1>
<button onClick={addItems}>Dodaj A i B</button>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default App;Napisz poprawną wersję addItems wykorzystującą prev
Zasada: Używaj setState(prev => …) gdy:
- nowa wartość zależy od poprzedniej
- aktualizujesz licznik
- aktualizujesz tablicę
- aktualizujesz obiekt
Twój komentarz