Come organizzare il frontend di una app React + TypeScript
Un esempio pratico con un’app per volantini dei supermercati
Quando un frontend React inizia a crescere, il problema non è più scrivere codice, ma capire dove metterlo.
Componenti che chiamano API, hook che fanno rendering, file enormi difficili da mantenere: se non c’è una struttura chiara, il debito tecnico arriva molto in fretta.
In questo articolo vediamo come organizzare il frontend di una app React + TypeScript, usando come esempio concreto un’app per la gestione dei volantini dei supermercati (prodotti, tag, campagne, stagionalità).
L’idea chiave: separare le responsabilità
Il frontend funziona bene quando ogni parte ha un solo motivo per cambiare.
Per semplificare, possiamo pensarlo come composto da 5 grandi aree:
UI (quello che l’utente vede)
Logica (come funziona la pagina)
Dati (che forma hanno)
Backend (da dove arrivano)
Utility (supporto)
Vediamole una per una.
La struttura delle cartelle
Una struttura semplice, ma molto efficace, è questa:
src/
├─ components/
├─ pages/
├─ hooks/
├─ services/
├─ types/
├─ utils/
└─ App.tsx
Non è “l’unica giusta”, ma è un ottimo punto di partenza per progetti reali.
components/: la UI pura
I componenti servono solo a una cosa: mostrare dati.
Esempi tipici in una app volantini:
components/
├─ ProductCard.tsx
├─ TagBadge.tsx
└─ FlyerProductTile.tsx
Qui:
ricevi dati tramite
propsmostri informazioni
gestisci eventi UI (click, hover)
Ma:
non chiami API
non gestisci flussi complessi
non conosci il backend
Un buon componente potrebbe vivere tranquillamente anche in un altro progetto.
pages/: le viste dell’applicazione
Le pagine sono il punto di incontro tra UI e logica.
pages/
├─ ProductsPage.tsx
├─ FlyerEditorPage.tsx
└─ CampaignPage.tsx
Qui succede che:
usi gli hook
componi i componenti
organizzi il layout della schermata
La pagina non sa come arrivano i dati, sa solo che li riceve.
hooks/: come funziona davvero l’app
Gli hook sono il cervello dell’applicazione.
hooks/
├─ useProducts.ts
├─ useTags.ts
└─ useCampaigns.ts
Un hook tipico:
chiama un service
gestisce loading / error
prepara i dati per la UI
Concettualmente:
useProducts()
→ chiama il backend
→ restituisce prodotti pronti da usare
Regola importante:
👉 gli hook non contengono JSX, solo logica.
services/: parlare con il backend
La cartella services è l’unico posto in cui il frontend parla con l’esterno.
services/
├─ api.ts
├─ productService.ts
├─ tagService.ts
└─ campaignService.ts
Qui trovi:
chiamate HTTP
configurazioni Axios / fetch
integrazioni con API
Se domani cambia il backend, modifichi solo questa cartella.
types/: il contratto dei dati
types è spesso sottovalutata, ma è fondamentale.
types/
├─ Product.ts
├─ Tag.ts
├─ Campaign.ts
└─ Flyer.ts
Qui definisci:
che cos’è un prodotto
che forma ha un tag
che dati arrivano dalle API
Queste interfacce sono il contratto tra frontend e backend.
Se qualcosa cambia, TypeScript ti avvisa subito.
utils/: funzioni di supporto
Infine, le utility:
utils/
├─ formatWeight.ts
├─ groupByCategory.ts
└─ dateHelpers.ts
Sono funzioni:
pure
riutilizzabili
indipendenti da React
Perfette per logica trasversale.
Un flusso reale: lista prodotti
Vediamo come tutto si collega nella pratica:
ProductsPage
↓
useProducts
↓
productService.getProducts
↓
LocalProduct[]
↓
ProductCard
Ogni livello fa una sola cosa, e la fa bene.
Le regole mentali da ricordare
Se devi portarti a casa solo questo:
components → come appare qualcosa
pages → cosa contiene una vista
hooks → come funziona
services → da dove arrivano i dati
types → che forma hanno i dati
Segnali di cattiva architettura 🚨
Se vedi:
componenti che chiamano API
hook con JSX dentro
services che importano React
tipi TypeScript definiti nei componenti
…probabilmente qualcosa va ripensato.
Conclusione
Una buona struttura frontend non serve a scrivere più codice, ma a:
leggere meglio quello esistente
ridurre gli errori
far crescere l’app senza paura
Soprattutto in applicazioni complesse come quelle per la gestione dei volantini dei supermercati, questa separazione fa davvero la differenza.

