Skip to content

RN Lezione 3: Componenti, JSX e Props

  • Capire il paradigma a componenti di React
  • Scrivere JSX correttamente
  • Usare props per passare dati tra componenti
  • Comporre componenti insieme

In React, tutto è un componente. Un componente è una funzione che ritorna JSX (markup).

// Componente semplice
const Saluto = () => {
return <Text>Ciao!</Text>;
};
// Uso nel componente genitore
<Saluto />
VantaggioSpiegazione
RiutilizzoScrivi una volta, usi ovunque
SeparazioneOgni pezzo UI è indipendente
TestabilitàTesti ogni componente da solo
LeggibilitàCodice più facile da leggere e mantenere
  1. Nome in maiuscolo: Card ✅, card
  2. Una funzione che ritorna JSX
  3. Si usa come tag HTML: <Card />
// ✅ Corretto
const Card = () => {
return <Text>Ciao</Text>;
};
// ❌ SBAGLIATO — nome minuscolo
const card = () => {
return <Text>Ciao</Text>;
};

JSX è un’estensione di JavaScript che sembra HTML ma è JavaScript.

  1. Un solo elemento radice — tutto dentro un <View> o <></>
  2. {} per inserire JavaScript nel markup
  3. style={} prende un oggetto, non una stringa
  4. I commenti JSX: {/* commento */}
// ✅ Corretto — un solo View radice
return (
<View>
<Text>Ciao</Text>
<Text>Mondo</Text>
</View>
);
// ✅ Corretto — Fragment (<> = View senza stili)
return (
<>
<Text>Ciao</Text>
<Text>Mondo</Text>
</>
);
// ❌ SBAGLIATO — due elementi radice
return (
<Text>Ciao</Text>
<Text>Mondo</Text>
);
const nome = 'Mario';
return (
<View>
<Text>Ciao, {nome}!</Text>
<Text>{2 + 2}</Text>
<Text>{nome.toUpperCase()}</Text>
<Text>{nome.length > 3 ? 'Lungo' : 'Corto'}</Text>
{/* ↑ operatore ternario = if inline */}
</View>
);

Le props sono come parametri di funzione per i componenti.

// Definizione del componente Card
const Card = (props) => {
return (
<View style={styles.card}>
<Text style={styles.titolo}>{props.titolo}</Text>
<Text style={styles.descrizione}>{props.descrizione}</Text>
</View>
);
};
// Uso — passo dati come attributi
<Card
titolo="Python"
descrizione="Linguaggio di programmazione"
/>
<Card
titolo="JavaScript"
descrizione="Il linguaggio del web"
/>

Destrutturazione delle props (metodo preferito)

Section titled “Destrutturazione delle props (metodo preferito)”
// ✅ Preferito — destrutturazione nei parametri
const Card = ({ titolo, descrizione, autore = 'Anonimo' }) => {
// ↑ default se non passato
return (
<View style={styles.card}>
<Text style={styles.titolo}>{titolo}</Text>
<Text>{descrizione}</Text>
<Text>Autore: {autore}</Text>
</View>
);
};

⚠️ Non modificare mai le props! Sono come parametri di funzione:

// ❌ SBAGLIATO — non modificare le props
const Card = ({ titolo }) => {
titolo = 'Nuovo titolo'; // ERRORE!
return <Text>{titolo}</Text>;
};

4. Composizione — componenti dentro componenti

Section titled “4. Composizione — componenti dentro componenti”
// Componente piccolo: Avatar
const Avatar = ({ nome, colore }) => {
return (
<View style={[styles.cerchio, { backgroundColor: colore }]}>
<Text style={styles.iniziale}>{nome[0]}</Text>
</View>
);
};
// Componente medio: CardProfilo (USA Avatar dentro)
const CardProfilo = ({ nome, bio, colore }) => {
return (
<View style={styles.card}>
<Avatar nome={nome} colore={colore} />
<View style={styles.info}>
<Text style={styles.nome}>{nome}</Text>
<Text style={styles.bio}>{bio}</Text>
</View>
</View>
);
};
// Componente principale: App (USA CardProfilo dentro)
export default function App() {
return (
<View style={styles.container}>
<CardProfilo nome="Mario" bio="Studente 4A" colore="blue" />
<CardProfilo nome="Sofia" bio="Studente 4B" colore="red" />
<CardProfilo nome="Luca" bio="Studente 4A" colore="green" />
</View>
);
}

La prop speciale children contiene tutto ciò che è tra i tag di apertura e chiusura.

// Contenitore generico
const Card = ({ children, style }) => {
return (
<View style={[styles.card, style]}>
{children} {/* ← tutto ciò che sta dentro <Card>...</Card> */}
</View>
);
};
// Uso
<Card style={{ backgroundColor: '#e3f2fd' }}>
<Text>Questo è dentro la card</Text>
<Text>Anche questo</Text>
</Card>
Section titled “Pattern: layout con header, content, footer”
const Pagina = ({ header, children, footer }) => {
return (
<View style={{ flex: 1 }}>
<View style={styles.header}>{header}</View>
<View style={styles.content}>{children}</View>
<View style={styles.footer}>{footer}</View>
</View>
);
};
// Uso
<Pagina
header={<Text style={styles.titolo}>Home</Text>}
footer={<Text>© 2026</Text>}
>
<Text>Contenuto della pagina</Text>
<Text>Altro contenuto</Text>
</Pagina>

6. Esempio guidato: Schermata profilo composta

Section titled “6. Esempio guidato: Schermata profilo composta”
import { View, Text, StyleSheet } from 'react-native';
// --- Sotto-componenti ---
const Avatar = ({ nome, colore }) => (
<View style={[styles.avatar, { backgroundColor: colore }]}>
<Text style={styles.iniziale}>{nome[0]}</Text>
</View>
);
const Badge = ({ testo, colore }) => (
<View style={[styles.badge, { backgroundColor: colore + '20' }]}>
<Text style={[styles.badgeTesto, { color: colore }]}>{testo}</Text>
</View>
);
const InfoRiga = ({ label, valore }) => (
<View style={styles.riga}>
<Text style={styles.label}>{label}</Text>
<Text style={styles.valore}>{valore}</Text>
</View>
);
// --- Componente principale ---
export default function App() {
return (
<View style={styles.container}>
<View style={styles.card}>
<Avatar nome="Mario" colore="#3498db" />
<Text style={styles.nome}>Mario Rossi</Text>
<Text style styles={styles.ruolo}>Studente 4A Informatica</Text>
<View style={styles.badgeRow}>
<Badge testo="Python" colore="#2ecc71" />
<Badge testo="React" colore="#3498db" />
<Badge testo="Flet" colore="#9b59b6" />
</View>
<View style={styles.separatore} />
<InfoRiga label="Età" valore="17" />
<InfoRiga label="Scuola" valore="ITI Fermi" />
<InfoRiga label="Media" valore="8.5" />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f0f4f8',
},
card: {
backgroundColor: 'white',
padding: 30,
borderRadius: 20,
alignItems: 'center',
width: '85%',
elevation: 5,
shadowColor: '#000',
shadowOpacity: 0.1,
shadowRadius: 10,
},
avatar: {
width: 80,
height: 80,
borderRadius: 40,
justifyContent: 'center',
alignItems: 'center',
marginBottom: 15,
},
iniziale: {
fontSize: 32,
fontWeight: 'bold',
color: 'white',
},
nome: {
fontSize: 22,
fontWeight: 'bold',
},
ruolo: {
fontSize: 14,
color: 'grey',
marginBottom: 15,
},
badgeRow: {
flexDirection: 'row',
gap: 8,
marginBottom: 15,
},
badge: {
paddingHorizontal: 12,
paddingVertical: 4,
borderRadius: 12,
},
badgeTesto: {
fontSize: 12,
fontWeight: '600',
},
separatore: {
width: '100%',
height: 1,
backgroundColor: '#eee',
marginBottom: 15,
},
riga: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
marginBottom: 8,
},
label: {
color: 'grey',
},
valore: {
fontWeight: '600',
},
});

Nota: c’è un errore voluto nel codice sopra (style styles nella riga del ruolo). Trovalo e correggilo! 🐛


ConcettoSintassi
Componenteconst Card = () => { return <View>...</View>; }
Propsconst Card = ({ titolo, ... }) => { ... }
Default propsconst Card = ({ titolo = 'Default' }) => { ... }
Children{children} tra i tag
Fragment<> ... </>
JSX JS{variabile} o {funzione()}

Crea una schermata con:

  1. Componente Prodotto che accetta props: nome, prezzo, colore
  2. Mostra nome (grande, grassetto) e prezzo (verde, con €)
  3. Un badge con la prima lettera del nome come sfondo colorato
  4. Usa la card dentro App con almeno 4 prodotti diversi
  • Tutti gli stili in StyleSheet.create()
  • Props destrutturate
  • Default per il colore ('#ccc')
  • flexWrap: 'wrap' per disporre le card su più righe