Skip to content

02. useState i useReducer

This content is not available in your language yet.

useState i useReducer

Stan to dane, które komponent “pamięta” między renderami. useState to najprostszy sposób na stan lokalny — idealne dla pojedynczych wartości. useReducer to wzorzec dla złożonego stanu z wieloma powiązanymi akcjami — jak mini-Redux w komponencie.

  1. Co to jest stan w React? — Dane, które komponent śledzi i które powodują re-render przy zmianie
  2. Jak działa useState? — Zwraca parę: aktualna wartość + funkcja setter
  3. Kiedy useState nie wystarczy? — Wiele powiązanych wartości, złożone przejścia stanów
  4. Jak działa useReducer? — Czysty reducer (state, action) => newState, dispatch akcji
  1. useState — podstawy — deklaracja, odczyt, aktualizacja, re-render
  2. Funkcja updatersetCount(c => c + 1) vs setCount(count + 1) — różnica w batching
  3. Stan obiektowy — dlaczego nie mutować bezpośrednio, spread operator
  4. useReducer — wzorzec — reducer, akcje, dispatch
  5. Kiedy co używać — tabela decyzyjna: useState vs useReducer

Schemat

Diagram przepływu: Zdarzenie użytkownika → dispatch(action) → reducer(state, action) → nowy state → re-render. Porównaj obok z useState: Zdarzenie → setState → nowy state → re-render.

Przykład kodu JSX

Ten sam licznik zaimplementowany najpierw z useState, potem z useReducer. Pokaż kiedy useReducer jest czytelniejszy (koszyk zakupów z add/remove/clear).

Zawartość:

  • useState — deklaracja, odczyt, setter
  • Przykład: licznik, formularz z jednym polem
  • Schemat re-render po setState
  • Podstawowe reguły hooków (tylko w komponentach funkcyjnych)

Forma: 10 slajdów, 10 minut prezentacji

Ocena: 3.0
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Licznik: {count}</p>
<button onClick={() => setCount(c => c + 1)}>+</button>
<button onClick={() => setCount(c => c - 1)}>-</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}
import { useReducer } from 'react';
const initialState = { items: [], total: 0 };
function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM':
return {
items: [...state.items, action.payload],
total: state.total + action.payload.price,
};
case 'REMOVE_ITEM':
return {
items: state.items.filter(item => item.id !== action.payload),
total: state.total - state.items.find(i => i.id === action.payload).price,
};
case 'CLEAR':
return initialState;
default:
return state;
}
}
function Cart() {
const [state, dispatch] = useReducer(cartReducer, initialState);
return (
<div>
<p>Produkty: {state.items.length}</p>
<p>Suma: {state.total}</p>
<button onClick={() => dispatch({ type: 'ADD_ITEM', payload: { id: 1, name: 'Kurs React', price: 99 } })}>
Dodaj
</button>
<button onClick={() => dispatch({ type: 'CLEAR' })}>
Wyczyść koszyk
</button>
</div>
);
}

Przykład 3 — Pułapka stale closure (dlaczego updater jest ważny)

Dział zatytułowany „Przykład 3 — Pułapka stale closure (dlaczego updater jest ważny)”
// ŹLE: może dać błędny wynik przy szybkim klikaniu
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1); // count może być "starym" count z closure!
setCount(count + 1); // oba sety używają tej samej wartości count
};
// Wynik po kliknięciu: +1, nie +2!
// DOBRZE: updater zawsze dostaje najnowszą wartość
const handleClickSafe = () => {
setCount(c => c + 1); // c = aktualna wartość
setCount(c => c + 1); // c = zaktualizowana wartość po poprzednim secie
};
// Wynik po kliknięciu: +2
}

Zacznij od problemu

Zapytaj klasę: “Co by się stało, gdyby kliknięcie przycisku nie zapamiętało ile razy kliknęliście?” — to motywuje po co jest stan.

Wizualizacja re-renderu

Na slajdzie narysujcie dwa stany komponentu obok siebie — przed i po setState. Podświetlcie co się zmieniło w JSX.

Analogia do useReducer

useReducer to jak automat vendingowy: wrzucasz monetę (dispatch akcji), automat wykonuje logikę (reducer) i wydaje produkt (nowy stan). Nie dotykasz wewnętrznych kółek!

Typowe pytanie na Q&A

“Czy setState jest synchroniczny?” — Nie! React batches aktualizacje stanu. Nowy stan jest dostępny dopiero po re-renderze.

Stan to serce każdej aplikacji React!

Bez stanu aplikacja byłaby statyczną stroną. Zrozumienie useState i useReducer to klucz do tworzenia interaktywnych interfejsów. Ten temat bezpośrednio przyda się w projekcie semestralnym!