Découverte des Hooks en React : Construire un Mini Pokédex avec useState, useEffect et un Hook personnalisé

Par abenkarrouch, 20 février, 2025
React_bannière

Introduction aux Hooks en React

Dans le dernier blog, on a découvert les composants en React et comment les props permettent de passer des données. Aujourd’hui, on va explorer un concept important et très utile qui permet de gérer l’état et les effets dans les applications React : les Hooks.

1. Qu’est-ce qu’un Hook en React ?

Les Hooks sont des fonctions qui permettent d’utiliser l’état et d’autres fonctionnalités de React dans des composants fonctionnel. Avant leur introduction dans la version 16.8, seuls les composants de classe pouvaient gérer un état. Avec les Hooks, les composants fonctionnels sont devenus plus puissants et faciles à écrire.

Voici quelques Hooks assez commun :

  • useState : Permet de gérer un état local dans un composant.
  • useEffect : Sert à gérer les effets secondaires (comme les appels API ou la mise à jour du DOM).
  • useContext : Utilisé pour accéder à un contexte global sans passer de props.
  • useRef : Permet d’accéder directement à un élément du DOM.

Nous allons nous concentrer aujourd’hui sur useState et useEffect avec des exemples simples.

2. Utilisation de useState

useState permet d’ajouter un état local à un composant fonctionnel. Voici un exemple simple :

import React, { useState } from 'react';

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

  return (
    <div>
      <p>Valeur du compteur : {compteur}</p>
      <button onClick={() => setCompteur(compteur + 1)}>Incrémenter</button>
    </div>
  );
}

export default Compteur;

Dans cet exemple :

  • useState(0) initialise un état compteur avec la valeur 0.
  • setCompteur est une fonction qui met à jour la valeur de compteur.
  • Un bouton permet d’incrémenter le compteur à chaque clic.

3. Utilisation de useEffect

useEffect permet d’exécuter du code après le rendu du composant. On l’utilise souvent pour les appels API ou la mise à jour du DOM.

Exemple :

import React, { useState, useEffect } from 'react';

function Horloge() {
  const [heure, setHeure] = useState(new Date().toLocaleTimeString());

  useEffect(() => {
    const interval = setInterval(() => {
      setHeure(new Date().toLocaleTimeString());
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return <h2>Il est {heure}</h2>;
}

export default Horloge;

Explication :

  • useEffect fait un intervalle qui met à jour l'heure chaque seconde.
  • La fonction retournée par useEffect (clearInterval) est exécutée lors du démontage du composant pour pas qu'il roule à l'infinie.
  • Le [] le deuxième argument signifie que l’effet s’exécute une seule fois après le premier rendu, on pourrait ajouter un état à écouter pour que l'effet s'execute à chaque changement

4. Création d’un Hook personnalisé : useFetch avec PokeAPI

Les Hooks personnalisés permettent de réutiliser des logiques spécifiques tout en sauvant des lignes de codes. On va créer un Hook useFetch qui récupère des données depuis une API les affiche.

Dans cette exemple, on va utiliser PokeAPI pour faire un mini pokedex.

Création du Hook useFetch.js

import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setData(data);
        setLoading(false);
      })
      .catch((err) => {
        setError(err);
        setLoading(false);
      });
  }, [url]);

  return { data, loading, error };
}

export default useFetch;

Utilisation du Hook dans un composant App.js

import './App.css';
import { PokemonDetails } from './components/PokemonDetails';
import useFetch from './hooks/usefetch';
import { useState } from 'react';

function App() {
  const [nom, setNom] = useState('');
  const { data } = useFetch('https://pokeapi.co/api/v2/pokemon/'+nom);

  return (
    <div className="App">
      <div className='pokedex-content'>
          {data && <PokemonDetails data={data} />}
            <form>
              <label>Numéro ou nom du pokémon</label>
              <div className='input-group'>
                <input onChange={(e) => setNom(e.target.value.toLowerCase())} type='text' placeholder='Chercher un pokémon' />
              </div>
            </form>
          </div>
      </div>
    </div>
  );
}

export default App;

Ce qui se passe dans PokemonDetails.js

import React from 'react';

export const PokemonDetails = ({ data }) => {
  return (
    <div className="pokemon-details">
      <div className="pokemonScreen">
        <img src={data.sprites.versions['generation-v']['black-white'].animated.front_default} alt={data.name} />
        <h3>{data.name.charAt(0).toUpperCase() + data.name.slice(1)}</h3>
      </div>
    </div>
  );
}

Aperçu

Mini Pokedex Demo

Résumer de ce qui se passe

  1. Le composant App utilise le Hook personnalisé useFetch pour récupérer les données d'un Pokémon depuis l'API PokeAPI.
  2. useState est utilisé pour gérer l'état nom, qui représente le nom ou le numéro du Pokémon à rechercher.
  3. Lorsqu'un utilisateur tape dans le champ de saisie, l'état nom est mis à jour avec la valeur en minuscules grâce au useState.
  4. Les données récupérées sont passées au composant PokemonDetails en tant que props, comme on je l'ai montré la semaine dernière pour afficher les détails du Pokémon.
  5. Le composant PokemonDetails reçoit les données du Pokémon en tant que prop.
  6. Il affiche une image en format gif du Pokémon et son nom formaté avec la première lettre en majuscule.
  7. Les détails sont affichés dans une div avec la classe pokemon-details.

Ressources supplémentaires

Si vous avez des difficultés vous pouvez regarder ou cloner mon Dépôt GitHub pour comprendre.Vous y trouverez le code source complet et des instructions détaillées.

Conclusion

Aujourd’hui, on a appris les Hooks en React, en nous concentrant sur useState et useEffect, et on a vu comment créer un Hook personnalisé pour simplifier la récupération de données. Les Hooks rendent les composants fonctionnels plus puissants et réutilisables.

Dans le prochain blog, on va explorer le routing avec React Router pour naviguer entre différentes pages dans une application React.

Sources

Étiquettes

Commentaires3

hekram

il y a 1 mois 1 semaine

Article impressionnant ! Ton blog explique bien et détaille clairement les concepts de useState et useEffect. J'ai vraiment aimé le fait que tu aies utilisé des exemples de code clairs. En passant, l'utilisation de la PokeAPI avec les exemples de code a rendu la compréhension de useState et useEffect encore plus facile. Juste une petite question : Y a-t-il des cas où l'utilisation de useRef serait plus adaptée que useState?

La différence entre useState et useRef est que useState provoque un rerender lorsque la valeur est changé alors qu’un useRef ne provoque aucun rerender.

Par exemple dans le mini pokedex, je mets à jour la recherche à chaque fois que j'appuie sur une touche à l’aide d’un useState qui influence les valeurs du hook personnalisé qui récupère les donnés du pokemon correspondant, ce qui provoque un rerender. Si je voulais seulement appliquer la recherche lorsque l’utilisateur ait terminé d’écrire et qu’il a appuyé un bouton de confirmation, j’aurais utilisé un useRef pour seulement faire la recherche une fois, puisque je n’ai pas besoin de rerender à chaque fois.

adelaa

il y a 1 mois 1 semaine

Super article ! Les explications sur useState et useEffect sont claires, et l’exemple du Pokédex aide bien à comprendre. Juste une question : comment éviter que useEffect ne fasse trop d’appels API ? Hâte de lire la suite ! 😊