Les Fondamentaux de React pour Débutants

Cet article présente les bases essentielles de React, en couvrant les concepts clés, l'installation et les hooks intégrés.

1. Créer et imbriquer des composants

Une application React est cosntruite à partir de composants. Un composant représente une partie de l'interface utilisateur (UI) avec sa propre logique et son apparence. Il peut être aussi petit qu'un bouton ou aussi grand qu'une page entière.

Les composants React doivent commencer par une majuscule, tandis que les balises HTML doivent être en minuscules.

function MonBouton() {
  return (
    <button>Je suis un bouton</button>
  );
}

export default function MonApp() {
  return (
    <div>
      <h1>Bienvenue dans mon application</h1>
      <MonBouton />
    </div>
  );
}

2. Utiliser JSX

JSX est plus strict que HTML. Vous devez fermer les balises, comme <br />. Un composant ne peut pas retourner plusieurs balises JSX ; elles doivent être enveloppées dans un parent commun, comme <div>...</div> ou <>...</>.

function PageAPropos() {
  return (
    <>
      <h1>À propos</h1>
      <p>Bonjour tout le monde.<br />Comment allez-vous ?</p>
    </>
  );
}

3. Ajouter des styles

En React, utilisez className pour spécifier une classe CSS, similaire à l'attribut class en HTML.

<img className="utilisateur" />

.utilisateur {
  background: red;
}

Styles en ligne :

<div style={{width: "300px", backgroundColor: "red"}}></div>

4. Afficher des données

Utilisez { } dans JSX pour exécuter du code JavaScript.

const [visible, setVisible] = useState(false);
const titre = "Titre";
return (
  <>
    {visible ? <h1>{titre}</h1> : null}
  </>
);

Pour assigner une variable JavaScript à un attribut HTML, utilisez { } et non des guillemets.

<img src="utilisateur" />    // Passe la chaîne "utilisateur" à src
<img src={userPng} />        // Passe la variable userPng à src

5. Rendu conditionnel

React n'a pas de syntaxe spéciale pour les conditions ; utilisez du JavaScript standard.

let contenu;
if (estConnecte) {
  contenu = <PanneauAdmin />;
} else {
  contenu = <FormulaireConnexion />;
}
return (
  <div>
    {contenu}
  </div>
);

// Opérateur ternaire ?
<div>
  {estConnecte ? (
    <PanneauAdmin />
  ) : (
    <FormulaireConnexion />
  )}
</div>

// Opérateur logique &&
<div>
  {estConnecte && <PanneauAdmin />}
</div>

6. Rendu de listes

N'oubliez pas de définir l'attribut key, similaire à :key dans Vue.js.

const produits = [{id: 1, titre: "nom1"}, {id: 2, titre: "nom2"}];

return (
  <ul>
    {produits.map(produit =>
      <li key={produit.id}>
        {produit.titre}
      </li>
    )}
  </ul>
);

7. Réagir aux événements

Notez que onClick={handleClick} n'a pas de parenthèses. Ne déclenchez pas la fonction de gestion d'événement ; passez la fonction à l'événement. React l'appellera lors du clic.

function MonBouton() {
  function handleClick() {
    alert('Vous m\'avez cliqué !');
  }

  return (
    <button onClick={handleClick}>
      Cliquez-moi
    </button>
  );
}

8. Mettre à jour l'interface

useState (similaire à ref() ou reactive() dans Vue.js) crée des données réactives qui mettent à jour l'interface lorsqu'elles changent.

Lorsque React re-rend un composant :

  • React appelle à nouveau votre fonction
  • La fonction retourne un nouvel instentané JSX
  • React met à jour l'interface pour correspondre à cet instantané
import { useState } from 'react';

export default function MonApp() {
  return (
    <div>
      <h1>Compteurs qui se mettent à jour séparément</h1>
      <MonBouton />
      <MonBouton />
    </div>
  );
}

function MonBouton() {
  const [compteur, setCompteur] = useState(0);

  function handleClick() {
    setCompteur(compteur + 1);
  }

  return (
    <button onClick={handleClick}>
      Cliqué {compteur} fois
    </button>
  );
}

9. Utiliser les hooks

Les fonctions commençant par use sont appelées hooks. useState est un hook intégré à React. Vous pouvez créer vos propres hooks en combinant des hooks existants.

Les hooks sont plus stricts que les fonctions normales. Vous ne devez les appeler qu'au niveau supérieur de votre composant (ou d'autres hooks). Si vous voulez utiliser useState dans une condition ou une boucle, extrayez un nouveau composant et utilisez-le à l'intérieur.

10. Partager des données entre composants

Remontez la variable à un parent commun et passez-la via les props.

export default function MonApp() {
  const [compteur, setCompteur] = useState(0);

  function handleClick() {
    setCompteur(compteur + 1);
  }

  return (
    <div>
      <h1>Compteurs qui se mettent à jour ensemble</h1>
      <MonBouton compteur={compteur} onClick={handleClick} />
      <MonBouton compteur={compteur} onClick={handleClick} />
    </div>
  );
}

function MonBouton({ compteur, onClick }) {
  return (
    <button onClick={onClick}>
      Cliqué {compteur} fois
    </button>
  );
}

11. Principes de conception des états (state)

Suivez ces principes pour une meilleure gestion des états :

  1. Fusionner les états liés : si vous mettez toujours à jour deux états en même temps, fusionnez-les en un seul.
  2. Éviter les états contradictoires : évitez les structures où des états peuvent s'opposer.
  3. Éviter les états redondants : ne stockez pas des informations calculables à partir des props ou d'autres états.
  4. Éviter les états dupliqués : la duplication rend la synchronisation difficile.
  5. Éviter les états imbriqués : privilégiez une structure plate pour faciliter les mises à jour.

Installation

1. Démarrer un nouveau projet React
  • Outil de base : npx create-react-app
  • Frameworks full-stack :
    • Next.js : npx create-next-app@latest
    • Remix : npx create-remix
2. Utiliser TypeScript

TypeScript supporte JSX nativement. Ajoutez @types/react et @types/react-dom pour une compatibilité complète.

npm install @types/react @types/react-dom

Hooks intégrés

Hooks d'état

useState est le hook principal pour gérer l'état local.

Hooks de contexte

Le contexte permet à un composant de recevoir des informations d'un ancêtre sans les passer via les props.

function Bouton() {
  const theme = useContext(ThemeContext);
  // ...
}

Hooks de référence

useRef permet de stocker des informations qui ne sont pas utilisées pour le rendu, comme des nœuds DOM ou des ID de minuteur.

const iptRef = useRef(null);
const minuteur = useRef(null);

useEffect(() => {
  iptRef.current.focus();
  minuteur.current = setInterval(() => {
    faireQuelqueChose();
  }, 100);
  return () => {
    clearInterval(minuteur.current);
  };
}, []);

return <input ref={inputRef} />;

Hooks d'effet

useEffect permet de gérer les effets de bord (appels réseau, DOM, etc.).

function ListeCartes() {
  const [liste, setListe] = useState([]);
  const [page, setPage] = useState(0);

  useEffect(() => {
    axios.get('/api/data').then((res) => {
      setListe(res.data);
    });
    return () => {
      // Nettoyage lors du démontage
    };
  }, []);

  useEffect(() => {
    // Exécuté lorsque page change
  }, [page]);

  return (
    <ol>
      {liste.map((item) => (
        <li key={item.id}>{item.titre}</li>
      ))}
    </ol>
  );
}

useLayoutEffect s'exécute avant le rendu à l'écran (peu utilisé).
useInsertionEffect s'exécute avant les modifications DOM par React (peu utilisé).

Hooks de performance
  • useMemo : met en cache des calculs coûteux.
  • useCallback : met en cache des définitions de fonctions.
  • useTransition : marque des transitions comme non bloquantes.
  • useDeferredValue : retarde la mise à jour de parties non critiques de l'interface.
Hooks de ressources

use(resource) permet de lire des ressources comme des Promises ou des contextes.

Contrairement aux autres hooks, use peut être appelé dans des boucles et des conditions. Il suspend le composant jusqu'à la résolution de la Promise.

import { createContext, use } from 'react';

const ThemeContext = createContext(null);

export default function MonApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Formulaire />
    </ThemeContext.Provider>
  );
}

function Formulaire() {
  return (
    <Panneau titre="Bienvenue">
      <Bouton show={true}>S'inscrire</Bouton>
      <Bouton show={false}>Se connecter</Bouton>
    </Panneau>
  );
}

function Panneau({ titre, enfants }) {
  const theme = use(ThemeContext);
  const className = 'panneau-' + theme;
  return (
    <section className={className}>
      <h1>{titre}</h1>
      {enfants}
    </section>
  );
}

function Bouton({ show, enfants }) {
  if (show) {
    const theme = use(ThemeContext);
    const className = 'bouton-' + theme;
    return (
      <button className={className}>
        {enfants}
      </button>
    );
  }
  return null;
}

import React, { ErrorBoundary, Suspense, use } from "react";

export function Utilisateur({ getUser }) {
  return (
    <ErrorBoundary fallback={<p>Erreur...</p>}>
      <Suspense fallback={<p>Chargement...</p>}>
        <Message getUser={getUser} />
      </Suspense>
    </ErrorBoundary>
  );
}

const getUser = axios.get("/api/user");

function Message({ getUser }) {
  const contenu = use(getUser);
  return <p>Utilisateur : {contenu}</p>;
}

useReducer

Une alternative à useState pour des états complexes impliquant plusieurs sous-valeurs.

Composants intégrés courants

Fragment

<Fragment> (ou <>...</>) permet de regrouper des éléments sans ajouter un nœud parent supplémentaire.

Attention :

  1. Si vous devez passer une key à un fragment, utilisez <Fragment key={votreKey}>.
  2. La transformation de <><Enfant /></> en [<Enfant />] ne réinitialise pas l'état (sauf si imbriqué).
Suspense
<Suspense fallback={<Chargement />}>
  {/* Affiche Chargement tant que QuelqueComposant n'est pas prêt */}
  <QuelqueComposant />
</Suspense>

children : contenu UI réel ; fallback : UI de remplacement pendant le chargement.

Étiquettes: React jsx useState useEffect useContext

Publié le 3 août à 06h55