webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Unelte
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Formulare
  12. 12Date și backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animații
  16. 16Testare
  17. 17Arhitectură
React · Lecția 2 din 7

State, derivare și reducer

useState corect, update-uri imutabile, state derivat și useReducer.

Actualizat

Ce este state

State = memoria unei componente: date care se schimbă în timp, din cauza interacțiunii (un input, un toggle, un contor). Când state-ul se schimbă, React re-randează componenta cu noua valoare.

De ce nu o variabilă simplă? O variabilă locală (let count = 0) se resetează la fiecare randare și schimbarea ei nu declanșează nicio actualizare a ecranului.

const [count, setCount] = useState(0)
  • countvaloarea curentă
  • setCountfuncția care o schimbă și cere o re-randare
  • 0valoarea inițială

Props vs state

Props State
Vine de la părinte componenta însăși
Se poate modifica în componentă nu da, prin setter
Rol configurare din afară memorie internă

Cum funcționează setter-ul

setCount(count + 1)        // valoare nouă
setCount(c => c + 1)       // updater — primește valoarea cea mai recentă
  • Setter-ul nu schimbă variabila imediat; programează o randare nouă. console.log(count) imediat după arată valoarea veche.
  • React grupează mai multe setări (batching) într-o singură randare.
  • Când noua valoare depinde de cea veche → updater function: setCount(c => c + 1) de 3 ori dă +3; setCount(count + 1) de 3 ori dă +1.

State-ul e imutabil

React compară state-ul vechi cu cel nou prin referință. Obiectele și array-urile le înlocuiești, nu le modifici — vezi Referințe și imutabilitate.

setUser({ ...user, name })                       // ✓
setTodos(todos => [...todos, newTodo])           // ✓
user.name = name; setUser(user)                  // ✗ aceeași referință → nicio re-randare

State derivat — nu-l stoca

Dacă o valoare se poate calcula din props sau state, calculeaz-o la randare. Nu o ține în alt useState.

// ✗ două surse de adevăr + un efect care le sincronizează
const [todos, setTodos] = useState([])
const [doneCount, setDoneCount] = useState(0)

// ✓ o singură sursă, restul derivat
const doneCount = todos.filter(t => t.done).length

Calcule chiar costisitoare → useMemo (sau React Compiler, care memoizează automat).

Unde ține state-ul — tipuri și când

Unde Când Exemplu
useState local îl folosește o singură componentă input, dropdown deschis
ridicat în părinte (lift state up) doi frați au nevoie de el filtru + listă
URL (?page=2) trebuie partajabil și să supraviețuiască reload-ului filtre, paginare, tab activ
Context multe componente adânci, schimbări rare tema, userul logat, limba
store (Zustand) global, schimbat des coș de cumpărături în SPA
cache de server state date de pe server Server state

Regula: cât mai jos posibil, ridici doar când e nevoie.

useReducer — când logica crește

Când un state are multe moduri de a se schimba, centralizezi logica într-un reducer — o funcție pură (state, action) => newState:

function todosReducer(state, action) {
  switch (action.type) {
    case 'add': return [...state, action.todo]
    case 'toggle': return state.map(t => (t.id === action.id ? { ...t, done: !t.done } : t))
    case 'remove': return state.filter(t => t.id !== action.id)
    default: return state
  }
}

const [todos, dispatch] = useReducer(todosReducer, [])
dispatch({ type: 'add', todo })
useState useReducer
1–3 valori simple state cu multe tranziții
logică în handler-e logică într-un singur loc, testabilă separat

Pe scurt

  • State = memoria componentei; setter-ul cere o re-randare.
  • Updater function când depinzi de valoarea veche; mereu obiecte noi.
  • Derivă ce poți calcula; ține state-ul cât mai jos; URL pentru ce trebuie partajat.

Surse oficiale

Exerciții

Ți-a fost utilă pagina?

Un click — fără cont.