🖱️ 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>
  );
}
📝 Exercices R05 ▶ Mini-projet : Login Form 🧠 QCM R05 Suivant : Listes →