PLANTA 4 · Sessió 4 · Taller: una web de zero (PratViatges)
L'obrador
Sistema a restaurar: Línia de muntatge de components
- 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.
El mètode del taller
PratViatges es construeix en 13 passos, cadascun amb una comprovació: crear el projecte amb Vite · netejar l'esquelet · tokens i estils globals · primer component (Peu) amb CSS Module · component amb props (Boto) · dades tipades · component que rep dades (TargetaDestinacio) · les pàgines · instal·lar React Router · taula de rutes · capçalera, Outlet i el canvi d'<a> a <Link> · ruta dinàmica amb useParams i 404 · revisió final amb npm run build.
Carpetes: src/components (peces reutilitzables i els seus .module.css), src/pagines (una per URL) i src/dades (les dades i els seus tipus).
Un component amb props: el Boto
Les props són els paràmetres del component. children és el que escrivim entre <Boto> i </Boto>.
import type { ReactNode } from 'react';
import estils from './Boto.module.css';
type Props = {
children: ReactNode;
variant?: 'primari' | 'secundari';
onClick?: () => void;
};
export default function Boto({ children, variant = 'primari', onClick }: Props) {
const classes =
variant === 'secundari' ? `${estils.boto} ${estils.secundari}` : estils.boto;
return (
<button className={classes} onClick={onClick}>
{children}
</button>
);
}| Fragment | Què fa |
|---|---|
import type { ReactNode } from 'react'; | Importa només el tipus: qualsevol cosa que React pugui dibuixar (text, elements, llistes). |
variant?: 'primari' | 'secundari'; | Prop opcional que només accepta aquests dos textos. |
variant = 'primari' | Valor per defecte si qui fa servir el Boto no posa variant. |
`${estils.boto} ${estils.secundari}` | Ajunta dues classes del CSS Module en un sol text, separades per un espai. |
onClick={onClick} | Passa la funció rebuda tal qual al botó real, sense cridar-la. |
{children} | Dibuixa el contingut que hi hagi entre les etiquetes del Boto. |
Dades tipades i un component que les rep
Les dades es declaren amb el seu type a src/dades. Cada targeta rep una destinació per props i no sap res de la resta de la llista.
export type Destinacio = { id: number; nom: string; pais: string; preu: number };
export function buscaDestinacio(id: number): Destinacio | undefined {
return destinacions.find((d) => d.id === id);
}
// pagines/Destinacions.tsx
{destinacions.map((d) => (
<TargetaDestinacio key={d.id} destinacio={d} />
))}| Fragment | Què fa |
|---|---|
Destinacio | undefined | find pot no trobar res: el tipus obliga a comprovar-ho abans de fer-la servir. |
destinacions.map((d) => …) | Converteix cada dada en una targeta. |
key={d.id} | Cada element d'una llista necessita una clau única i estable: l'id de la dada. |
destinacio={d} | La destinació baixa com a prop. |
Els errors típics del taller
| Missatge | Causa |
|---|---|
Cannot find module './Boto.module.css' (TS2307) | Falta src/vite-env.d.ts amb /// <reference types="vite/client" />. |
useHref() may be used only in the context of a <Router> | Hi ha un Link fora del BrowserRouter. |
Each child in a list should have a unique "key" prop | Falta la key al map. |
does not provide an export named 'default' | El component no té export default. |
| El hover tapa l'enllaç actiu | Especificitat: cal .enllac:hover:not(.actiu). |
Planta restaurada · Línia de muntatge de components
La línia de muntatge torna a produir components. PratViatges està llest per publicar.
- 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.