PLANTA 3 · Sessió 3 · Navegació amb React Router
El laberint de rutes
Sistema a restaurar: Ascensors i passadissos (rutes)
- Alerta
- Manual
- Reptes
- Mòdul
Aquesta planta ja té llum. Pots tornar-la a jugar per repassar, però la puntuació desada no canviarà.
Manual de la planta
0 / 4Desbloqueja les 4 pàgines del manual per obrir els reptes. Llegeix-les bé: els reptes en pregunten els detalls.
Per què necessitem un router
Una SPA (single page application) té un sol index.html. Si canviem de «pàgina» amb un estat i un if, la URL no canvia: no es pot compartir l'enllaç, el botó enrere del navegador no funciona i en recarregar tornem a l'inici. React Router fa que cada URL dibuixi un component.
Fem servir React Router 8, paquet react-router (el react-router-dom es va quedar a la versió 7), en mode declaratiu. <BrowserRouter> escolta la URL i embolcalla tota l'aplicació a main.tsx.
import { BrowserRouter } from 'react-router';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);La taula de rutes
A App.tsx declarem quina URL dibuixa quin component.
<Routes>
<Route element={<Disposicio />}>
<Route index element={<Inici />} />
<Route path="cataleg" element={<Cataleg />} />
<Route path="producte/:id" element={<Producte />} />
<Route path="contacte" element={<Contacte />} />
<Route path="*" element={<NoTrobada />} />
</Route>
</Routes>| Fragment | Què fa |
|---|---|
<Route element={<Disposicio />}> | Ruta pare sense path: només aporta la disposició comuna (capçalera i peu) a totes les filles. |
<Route index … /> | La pàgina que es veu quan la URL és exactament /. |
path="producte/:id" | :id és un tros variable: /producte/1, /producte/2… |
path="*" | Atrapa qualsevol URL que no hagi coincidit abans: la pàgina 404. |
Link, NavLink i Outlet
<a href>recarrega tota la pàgina i es perd l'estat.<Link to="/cataleg">canvia la URL sense recarregar.<NavLink>és un Link que sap si està actiu: aclassNameli passem una funció que rep{ isActive }.endal NavLink de/: sense, l'enllaç d'inici surt actiu a totes les pàgines.<Outlet />: el lloc de la disposició on es dibuixa la pàgina filla.
export default function Disposicio() {
const classe = ({ isActive }: { isActive: boolean }) => (isActive ? 'enllac actiu' : 'enllac');
return (
<div className="pagina">
<nav>
<NavLink to="/" end className={classe}>Inici</NavLink>
<NavLink to="/cataleg" className={classe}>Catàleg</NavLink>
</nav>
<main><Outlet /></main>
</div>
);
}Els hooks del router
useParams(): els trossos variables de la ruta. Sempre arriben com a text:Number(id)per convertir-los.useNavigate(): navegar des de codi.navega('/carro'),navega(-1)(enrere),navega('/', { replace: true }).useSearchParams(): la part de la URL després de?. Un cercador que viu a la URL es pot compartir.<Navigate to="/no-trobada" replace />: redirigeix mentre es dibuixa;replaceevita que la pàgina dolenta quedi a l'historial.
const { id } = useParams();
const navega = useNavigate();
const producte = buscaProducte(Number(id));
if (!producte) return <Navigate to="/no-trobada" replace />;
const [parametres, setParametres] = useSearchParams();
const cerca = parametres.get('cerca') ?? '';| Fragment | Què fa |
|---|---|
const { id } = useParams(); | Llegeix el :id de la ruta. Per a /producte/3, id val "3" (text). |
buscaProducte(Number(id)) | Converteix el text a número abans de buscar. |
<Navigate to="/no-trobada" replace /> | Si el producte no existeix, redirigeix a la 404 sense deixar rastre a l'historial. |
parametres.get('cerca') ?? '' | Si a la URL no hi ha ?cerca=, get() retorna null i el convertim en text buit. |
Planta restaurada · Ascensors i passadissos (rutes)
Ascensors operatius: cada URL torna a portar a la seva planta.
- XP
- 0
- Bonus ratxa
- 0
- Errors
- 0
- Pistes
- 0
- Estrelles
- ☆☆☆
Anota la lletra i la seva posició: al terrat hauràs de compilar l'ordre de reinici.