State Management — Cheat Sheet

Tag: state, frontend, react, redux, context, zustand, architecture

Livello: intermedio

TL;DR: La gestione dello stato definisce il flusso dei dati nell'applicazione. Scegliere il tool giusto dipende dalla frequenza di aggiornamento e dall'ambito dei dati.

Concetti chiave

Local state: dati isolati all'interno di un singolo componente (es. input di form, toggle).

Global state: dati condivisi tra componenti non direttamente correlati (es. carrello, sessione utente).

Server state: dati asincroni provenienti dal backend, che richiedono gestione di loading, cache ed errori.

URL state: stato memorizzato nei parametri della query string per filtri di ricerca e paginazione.

Il prop drilling avviene quando i dati passano attraverso molti componenti intermedi che non li utilizzano.

La Context API risolve il prop drilling ma può causare re-render dell'intero albero se non ottimizzata.

Librerie esterne come Zustand o Redux mantengono lo store separato dall'albero per aggiornamenti più mirati.

L'immutabilità è fondamentale: lo stato non si modifica mai direttamente, si creano sempre nuove referenze.

Lo stato derivato non va mai salvato a sua volta, ma va calcolato al volo durante il render.

Domande tipiche e risposte pronte

Q: Quando preferisci Context API rispetto a Redux o Zustand?R: Uso Context per dati che cambiano raramente come il tema. Per aggiornamenti frequenti preferisco Zustand per evitare re-render a cascata sui consumer.

Q: Come gestisci i dati in arrivo dalle API? Li metti nello store globale?R: No, evito di mescolare server state e client state. Uso tool dedicati come React Query per gestire cache, invalidazione e stati di caricamento.

Q: Cosa si intende per lifting state up?R: È la pratica di spostare lo stato al genitore comune più vicino, permettendo a più componenti figli di condividerlo e modificarlo tramite prop.

Insidie e errori comuni

Inserire ogni variabile nello store globale, aumentando la complessità e il rischio di bug.

Mutare lo stato direttamente invece di usare funzioni pure e copie dell'oggetto o array.

Duplicare lo stato derivato sincronizzandolo manualmente invece di ricalcolarlo.

Dimenticare di pulire listener o sottoscrizioni nei componenti che si smontano, causando memory leak.

Passare a Context provider oggetti inline creati a ogni render, forzando l'aggiornamento di tutti i consumer.

Snippet e comandiTypeScript

// Esempio di store globale minimale con Zustand
import { create } from 'zustand'

interface AuthState {
  user: string | null
  login: (user: string) => void
  logout: () => void
}

export const useAuthStore = create<AuthState>((set) => ({
  user: null,
  login: (user) => set({ user }),
  logout: () => set({ user: null }),
}))
Jarvis Interviews
Jarvis