Skip to content

RN Lezione 4: useState, Eventi e TextInput

  • Gestire lo stato locale con useState
  • Catturare eventi (onPress, onChangeText)
  • Usare TextInput e Button
  • Costruire form interattivi

useState permette a un componente di ricordare dati che cambiano.

import { useState } from 'react'; // ← importa useState
const Contatore = () => {
const [count, setCount] = useState(0);
// ↑ ↑ ↑
// valore funzione che valore iniziale
// lo aggiorna
const incrementa = () => {
setCount(count + 1); // ← aggiorna il valore
};
return (
<View>
<Text>Hai cliccato {count} volte</Text>
<Button title="+1" onPress={incrementa} />
</View>
);
};
  1. useState(0) → crea una variabile count inizializzata a 0
  2. setCount(nuovoValore)aggiorna il valore
  3. Quando setCount viene chiamato, il componente si ri-renderizza (si aggiorna la UI)
// Schema mentale:
// cost [valore, setValore] = useState(iniziale)
// ↑ ↑ ↑
// LEGGERE SCRIVERE PRIMA VOLTA
// ✅ Corretto
const [nome, setNome] = useState('Mario');
// ❌ Non modificare direttamente!
nome = 'Luigi'; // NON funziona — la UI non si aggiorna
setNome('Luigi'); // ✅ Corretto — la UI si aggiorna

import { Button } from 'react-native';
<Button
title="Cliccami" // Testo del bottone
onPress={funzione} // Funzione da chiamare al click
color="blue" // Colore (solo Android)
disabled={false} // Disabilitato?
/>
// 1. Funzione esterna (più leggibile)
const incrementa = () => {
setCount(count + 1);
};
<Button title="+1" onPress={incrementa} />
// 2. Arrow function inline (semplice)
<Button title="+1" onPress={() => setCount(count + 1)} />
// 3. NO: chiamata diretta (si esegue SUBITO!)
<Button title="+1" onPress={setCount(count + 1)} /> // ❌ ERRORE!

import { View, Text, Button, StyleSheet } from 'react-native';
import { useState } from 'react';
export default function App() {
const [count, setCount] = useState(0);
return (
<View style={styles.container}>
<Text style={styles.numero}>{count}</Text>
<View style={styles.riga}>
<Button
title="-1"
onPress={() => setCount(count - 1)}
color="red"
/>
<Button
title="Reset"
onPress={() => setCount(0)}
/>
<Button
title="+1"
onPress={() => setCount(count + 1)}
color="green"
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f5f5f5',
},
numero: {
fontSize: 60,
fontWeight: 'bold',
marginBottom: 30,
color: count < 0 ? 'red' : count > 10 ? 'green' : 'black',
},
riga: {
flexDirection: 'row',
gap: 10,
},
});

Nota: count nella style è calcolato inline — cambia colore in base al valore! 🎨


import { TextInput } from 'react-native';
import { useState } from 'react';
const FormNome = () => {
const [nome, setNome] = useState('');
return (
<View>
<TextInput
style={styles.input}
placeholder="Il tuo nome"
value={nome} // ← valore controllato
onChangeText={setNome} // ← equivalente a (text) => setNome(text)
/>
<Text>Ciao, {nome}!</Text>
</View>
);
};
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderColor: '#ccc',
padding: 12,
borderRadius: 8,
fontSize: 16,
marginBottom: 10,
},
});
ProprietàDescrizioneEsempio
valueValore controllatovalue={nome}
onChangeTextChiamata quando cambiaonChangeText={setNome}
placeholderTesto di suggerimentoplaceholder="Nome..."
secureTextEntryPer passwordsecureTextEntry={true}
multilineMulti riga (textarea)multiline={true}
keyboardTypeTipo tastierakeyboardType="numeric"
maxLengthMassimo caratterimaxLength={20}
editableDisabilita input?editable={false}
keyboardType="default" // Testo normale
keyboardType="numeric" // Solo numeri
keyboardType="email-address" // Email (@)
keyboardType="phone-pad" // Telefono
keyboardType="decimal-pad" // Numeri con virgola

import { View, Text, TextInput, Button, StyleSheet, Alert } from 'react-native';
import { useState } from 'react';
export default function App() {
const [nome, setNome] = useState('');
const [eta, setEta] = useState('');
const [inviato, setInviato] = useState(false);
const invia = () => {
if (!nome || !eta) {
Alert.alert('Errore', 'Compila tutti i campi!');
return;
}
setInviato(true);
};
const reset = () => {
setNome('');
setEta('');
setInviato(false);
};
if (inviato) {
return (
<View style={styles.container}>
<Text style={styles.titolo}>✅ Dati ricevuti!</Text>
<Text style={styles.dato}>Nome: {nome}</Text>
<Text style={styles.dato}>Età: {eta}</Text>
<Button title="Torna indietro" onPress={reset} />
</View>
);
}
return (
<View style={styles.container}>
<Text style={styles.titolo}>Chi sei?</Text>
<TextInput
style={styles.input}
placeholder="Nome"
value={nome}
onChangeText={setNome}
/>
<TextInput
style={styles.input}
placeholder="Età"
value={eta}
onChangeText={setEta}
keyboardType="numeric"
maxLength={3}
/>
<Button title="Invia" onPress={invia} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 30,
backgroundColor: '#f5f5f5',
},
titolo: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
input: {
width: '100%',
borderWidth: 1,
borderColor: '#ccc',
padding: 12,
borderRadius: 8,
fontSize: 16,
marginBottom: 12,
backgroundColor: 'white',
},
dato: {
fontSize: 18,
marginBottom: 8,
},
});

const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [errore, setErrore] = useState('');
const login = () => {
if (!email) {
setErrore('Inserisci l\'email');
return;
}
if (!password) {
setErrore('Inserisci la password');
return;
}
if (password.length < 6) {
setErrore('Password troppo corta (min 6 caratteri)');
return;
}
setErrore('');
Alert.alert('✅ Successo', 'Login effettuato!');
};

// Cambia stile in base allo stato
<TextInput
style={[
styles.input,
errore && styles.inputErrore, // ← bordo rosso se errore
]}
/>
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderColor: '#ccc',
padding: 12,
borderRadius: 8,
},
inputErrore: {
borderColor: 'red',
borderWidth: 2,
},
});

ConcettoCodice
useStateconst [x, setX] = useState(iniziale)
Aggiornare statosetX(nuovoValore)
Bottone<Button title="..." onPress={fn} />
TextInput<TextInput value={x} onChangeText={setX} />
AlertAlert.alert('Titolo', 'Messaggio')
Stile condizionalestyle={[base, cond && extra]}

🎯 Esercizio: “App Convertitore € → $”

Section titled “🎯 Esercizio: “App Convertitore € → $””

Crea un’app che:

  1. Un campo per importo in euro
  2. Un campo per il tasso di cambio (default: 1.08)
  3. Bottone “Converti”
  4. Mostra il risultato: X.XX € = Y.YY $
  5. Validazione: mostra errore se l’importo è vuoto o <= 0
  6. Quando il risultato > 100€, coloralo di verde
  7. Extra: bottone “Inverti” che scambia € e $
  • keyboardType="decimal-pad" per numeri con virgola
  • parseFloat(valore) per convertire stringa → numero
  • .toFixed(2) per arrotondare a 2 decimali