🖱️ Gestion des événements
En React, les événements utilisent la convention camelCase et reçoivent une fonction (pas une chaîne de caractères).
// HTML — attribut string, appel direct
<button onclick="handleClick()">Clic</button>
// React — prop camelCase, référence à une fonction
<button onClick={handleClick}>Clic</button>
<button onClick={() => handleClick(id)}>Clic avec arg</button>
// Événements courants
<button onClick={fn}> // clic souris
<input onChange={fn}> // changement de valeur
<input onFocus={fn} onBlur={fn}> // focus/blur
<form onSubmit={fn}> // soumission formulaire
<div onMouseEnter={fn}> // survol
// L'objet événement (SyntheticEvent React)
function handleChange(e) {
console.log(e.target.value); // valeur du champ
console.log(e.target.type); // type du champ
console.log(e.target.checked); // pour checkbox
}
🎛️ Inputs contrôlés
Un input contrôlé a sa valeur liée au state React. Chaque frappe met à jour le state, ce qui re-rend le composant et met à jour le champ.
function Formulaire() {
const [nom, setNom] = useState('');
const [email, setEmail] = useState('');
const [role, setRole] = useState('dev');
const [newsletter, setNewsletter] = useState(false);
return (
<form>
{/* Text input */}
<input type="text" value={nom} onChange={e => setNom(e.target.value)} />
{/* Email input */}
<input type="email" value={email} onChange={e => setEmail(e.target.value)} />
{/* Select */}
<select value={role} onChange={e => setRole(e.target.value)}>
<option value="dev">Développeur</option>
<option value="designer">Designer</option>
</select>
{/* Checkbox */}
<input
type="checkbox"
checked={newsletter}
onChange={e => setNewsletter(e.target.checked)}
/>
</form>
);
}
✅ Avec un input contrôlé, le state est la source de vérité. Cela permet de valider, formater et synchroniser facilement.
📬 Soumission de formulaire
function LoginForm() {
const [email, setEmail] = useState('');
const [motDePasse, setMotDePasse] = useState('');
const [soumis, setSoumis] = useState(false);
function handleSubmit(e) {
e.preventDefault(); // empêche le rechargement de la page
// Traiter les données
console.log('Connexion avec :', email);
setSoumis(true);
// Envoyer à une API
// fetch('/api/login', { method: 'POST', body: JSON.stringify({ email, motDePasse }) });
}
if (soumis) return <p>✅ Connecté en tant que {email}</p>;
return (
<form onSubmit={handleSubmit}>
<input type="email" value={email} onChange={e => setEmail(e.target.value)} required />
<input type="password" value={motDePasse} onChange={e => setMotDePasse(e.target.value)} required />
<button type="submit">Se connecter</button>
</form>
);
}
✅ Validation de formulaire
function FormInscription() {
const [form, setForm] = useState({ email: '', password: '' });
const [erreurs, setErreurs] = useState({});
function valider(champs) {
const errs = {};
if (!champs.email.includes('@')) errs.email = 'Email invalide';
if (champs.password.length < 8) errs.password = 'Min 8 caractères';
return errs;
}
function handleChange(e) {
const { name, value } = e.target;
const newForm = { ...form, [name]: value };
setForm(newForm);
setErreurs(valider(newForm));
}
function handleSubmit(e) {
e.preventDefault();
const errs = valider(form);
if (Object.keys(errs).length > 0) { setErreurs(errs); return; }
console.log('Formulaire valide :', form);
}
return (
<form onSubmit={handleSubmit}>
<input name="email" value={form.email} onChange={handleChange} />
{erreurs.email && <span style={{ color: 'red' }}>{erreurs.email}</span>}
<input name="password" type="password" value={form.password} onChange={handleChange} />
{erreurs.password && <span style={{ color: 'red' }}>{erreurs.password}</span>}
<button type="submit" disabled={Object.keys(erreurs).length > 0}>S'inscrire</button>
</form>
);
}