State Management — Cheat Sheet

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

Livello: intermedio

TL;DR: Pattern e strumenti per gestire in modo prevedibile i dati condivisi tra componenti, evitando il prop drilling e ottimizzando le performance di rendering.

Concetti chiave

Lo stato locale (Local State) appartiene a un singolo componente, gestito tipicamente con useState o useReducer.

Lo stato globale (Global State) è condiviso e accessibile da molteplici componenti ovunque nell'albero.

Prop Drilling: l'anti-pattern di passare dati attraverso molti livelli intermedi di componenti che non li usano direttamente.

Context API: soluzione nativa per il prop drilling, ideale per dati stabili e poco mutevoli (temi, auth, lingua).

Redux: architettura centralizzata basata su un singolo store, actions e reducers puri. Oggi si usa Redux Toolkit (RTK).

Zustand / Jotai: librerie moderne con boilerplate minimo. Zustand usa un approccio a store (simile a Redux), Jotai usa gli atomi.

Server State: dati provenienti dal backend. Strumenti come React Query o SWR gestiscono cache, fetching e sincronizzazione separatamente dallo stato UI.

Immutabilità: lo stato non va mai modificato per assegnazione diretta (state.x = 1), ma ricreato tramite copia (es. spread operator).

Domande tipiche e risposte pronte

Q: Quando usi Context API e quando Redux/Zustand?R: Uso Context per dati semplici e stabili come il tema o l'utente loggato. Passo a Zustand o Redux quando ho stati complessi, frequenti aggiornamenti parziali e mi serve un buon time-travel debugging.

Q: Come previeni i render inutili causati dallo stato globale?R: Estraggo solo i dati strettamente necessari usando selettori precisi. In Redux uso useSelector, in Zustand passo una funzione di selezione. Se serve, avvolgo i componenti complessi in React.memo.

Q: Perché lo stato in React o Redux deve essere immutabile?R: Perché per capire se c'è stata una modifica viene usata la strict equality (===). Se muto l'oggetto direttamente il riferimento non cambia e il framework non fa scattare il re-render.

Insidie e errori comuni

Mettere tutto nello stato globale: dati effimeri come il testo di un form input dovrebbero restare nello stato locale.

Mutare lo stato direttamente (es. state.items.push(newItem)) rompendo il ciclo di re-render e il time-travel debugging.

Usare Context API per stati che cambiano molto velocemente, causando il re-render a cascata di tutti i componenti che consumano il context.

Snippet e comandiTypeScript

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

interface CartState {
  items: string[]
  addItem: (item: string) => void
}

export const useCartStore = create<CartState>((set) => ({
  items: [],
  // Aggiornamento immutabile dello stato
  addItem: (item) => set((state) => ({ items: [...state.items, item] })),
}))

// Uso in un componente: seleziono solo la funzione, evito render inutili
// const addItem = useCartStore((state) => state.addItem)

Da ripassare

[ ] Architettura Flux e differenze con MVC

[ ] Configurazione base di Redux Toolkit (slice e store)

[ ] Pattern ad atomi in Jotai o Recoil

Jarvis Interviews
Jarvis