React
Preservare lo stato tra le route
Lo stato sopravvive a un cambio di route solo se il componente resta montato: spostalo sopra il router, oppure mettilo nell’URL, in un context o in storage.
In sintesi
- Il cambio di route smonta il componente e il suo useState sparisce.
- Lo stato che sta sopra Routes sopravvive alla navigazione.
- Filtri e pagina nell’URL sopravvivono a reload e link condivisi.
- replace evita una voce di cronologia per ogni tasto.
Lo stato sopravvive a un cambio di route solo se il componente che lo possiede resta montato: spostalo sopra il router, oppure mettilo nell’URL, in un context o nello storage, e decidi cosa deve azzerarsi.
Quando React smonta, lo stato muore
Un cambio di route sostituisce l’elemento dentro Routes: il componente della pagina precedente viene smontato e con lui cadono useState, i valori delle ref e le cache locali. Non è un bug, è la stessa regola che azzera un form quando cambi pagina.
Tre posti, tre costi
- Sopra il router: lo stato vive nell’app e non si perde; costa memoria finché la scheda resta aperta.
- Nell’URL: filtri e pagina sopravvivono a reload e link condivisi; costa una voce di cronologia per ogni scrittura.
- In storage: sopravvive alla chiusura del browser; costa una versione dello schema e una scadenza, altrimenti resta per sempre.
Filtri nell’URL
import { useSearchParams } from "react-router";
const [params, setParams] = useSearchParams();
const page = Number(params.get("page") ?? "1");
const query = params.get("q") ?? "";
function setQuery(next) {
setParams({ q: next, page: "1" }, { replace: true });
}
La pagina e il testo di ricerca arrivano dall’URL, quindi un reload non li perde e un link li porta con sé. replace evita una voce di cronologia per ogni tasto, altrimenti il tasto indietro diventa inutilizzabile.
Lo stato che deve restare fuori
function App() {
const [draft, setDraft] = useState(""); // survives route changes
return (
...
);
}
Tutto ciò che sta sopra Routes non viene smontato: la bozza sopravvive alla navigazione. Metti lì solo lo stato che deve davvero durare, perché ogni valore trattenuto è memoria che non si libera.
Il comando
npm create vite@latest router-demo -- --template react-ts
cd router-demo
npm install react-router
npm run dev
React Router è distribuito con licenza MIT; il progetto parte con Vite e la route si dichiara in src/App.tsx. Il pacchetto react-router contiene già i componenti del browser, quindi non serve il vecchio react-router-dom.
Record vivi nel catalogo
Tre record mostrano stato che vive oltre un singolo campo: expandable-tabs tiene la tab aperta, sidebar ricorda se è estesa, e la categoria input raccoglie i campi che quello stato lo producono.
La limitazione
Nessuno dei tre posti è gratis: lo stato sopra il router trattiene memoria, l’URL finisce nella cronologia e nei log del server, lo storage richiede una versione e una scadenza. La scelta sbagliata si vede tardi, quando un utente torna su una pagina e trova i dati di un altro.
Dove continuare
Le tab che vivono nell’URL sono in tab e URL; la navigazione da codice è in navigare con React Router; la stessa idea con i search params di Next.js è in paginazione e search params; il confronto fra i due setup è in Next.js vs Vite.
Domande frequenti
Perché lo stato si perde cambiando route?
Perché il componente della pagina viene smontato e React elimina il suo stato. Solo ciò che resta montato conserva i valori.
Conviene mettere i filtri nell’URL?
Sì quando l’utente deve condividere o ricaricare la vista. Costo: una scrittura di cronologia per aggiornamento, quindi usa replace e un debounce.
Dove metto una bozza di form da conservare?
Sopra il router se serve solo durante la sessione, in sessionStorage se deve sopravvivere a un reload, sul server se deve durare oltre la sessione.
Conservare tutto in un context è una buona idea?
No. Il context trattiene tutto finché l’app resta aperta e ogni aggiornamento rirenderizza chi lo legge: metti solo lo stato davvero condiviso.
Lo stato nell’URL è sicuro?
È pubblico: finisce nella cronologia, nei log e nei link condivisi. Non metterci token, email o dati personali.