« Max reacjsex » : différence entre les versions

 
(15 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
Voici une '''architecture ReactJS''' basée sur vos composants déclaratifs, en mettant l’accent sur les '''points clés de réactivité'''. Je vais structurer l’application avec :<br />
- Une hiérarchie de composants<br />
- La gestion d’état stratégique (local vs global)<br />
- Les dépendances réactives (conditions, effets)
-----
<span id="structure-de-fichiers-simplifiée"></span>
=== '''1. Structure de Fichiers (Simplifiée)''' ===
<syntaxhighlight lang="bash">src/
├── components/
│  ├── common/              # Composants réutilisables
│  │  ├── ZoneNumerique.jsx
│  │  ├── ZoneTexte.jsx
│  │  └── Bouton.jsx
│  ├── geoloc/              # Modules spécifiques
│  │  ├── Geoloc.jsx
│  │  └── CoordXY.jsx
│  └── formadresse/          # Formulaire d'adresse
│      ├── AttributAdresse.jsx
│      ├── CodePos.jsx
│      └── Ville.jsx
├── pages/
│  └── Application.jsx      # Point d'entrée
└── App.jsx                  # Racine React</syntaxhighlight>
-----
<span id="squellette-de-lapplication"></span>
=== '''2. Squellette de l’Application''' ===
<span id="a.-composants-de-base-réutilisables"></span>
Pour organiser l’arborescence des fichiers JSX et les imports dans une application React, il est important de structurer les fichiers de manière logique et modulaire. Voici une suggestion d’organisation sous forme de tableau, ainsi qu’une indication sur la manière de gérer les imports.
Pour organiser l’arborescence des fichiers JSX et les imports dans une application React, il est important de structurer les fichiers de manière logique et modulaire. Voici une suggestion d’organisation sous forme de tableau, ainsi qu’une indication sur la manière de gérer les imports.
 
== '''1.Exemple''' ==
<span id="arborescence-des-fichiers-jsx"></span>
<span id="arborescence-des-fichiers-jsx"></span>
=== Arborescence des fichiers JSX ===
=== Arborescence des fichiers JSX ===
Ligne 124 : Ligne 90 :


<span id="exemple-de-srccomponentszonetexte.jsx"></span>
<span id="exemple-de-srccomponentszonetexte.jsx"></span>
=== Exemple de <code>/src/components/ZoneTexte.jsx</code> ===
=== <code>/src/components/ZoneTexte.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';


const ZoneTexte = ({ value, onChange }) => {
const ZoneTexte = ({ value, onChange }) => {
   return <input type=&quot;text&quot; value={value} onChange={onChange} />;
   return <input type="text" value={value} onChange={onChange} />;
};
};


export default ZoneTexte;</syntaxhighlight>
export default ZoneTexte;</syntaxhighlight>
<span id="exemple-de-srccomponentszonenumerique.jsx"></span>
<span id="exemple-de-srccomponentszonenumerique.jsx"></span>
=== Exemple de <code>/src/components/ZoneNumerique.jsx</code> ===
=== <code>/src/components/ZoneNumerique.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';


const ZoneNumerique = ({ value, onChange }) => {
const ZoneNumerique = ({ value, onChange }) => {
   return <input type=&quot;number&quot; value={value} onChange={onChange} />;
   return <input type="number" value={value} onChange={onChange} />;
};
};


export default ZoneNumerique;</syntaxhighlight>
export default ZoneNumerique;</syntaxhighlight>
<span id="exemple-de-srccomponentsbouton.jsx"></span>
<span id="exemple-de-srccomponentsbouton.jsx"></span>
=== Exemple de <code>/src/components/Bouton.jsx</code> ===
=== <code>/src/components/Bouton.jsx</code> ===


<syntaxhighlight lang="jsx" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
Ligne 158 : Ligne 124 :
export default Bouton;</syntaxhighlight>
export default Bouton;</syntaxhighlight>
<span id="exemple-de-srccomponentscoordxy.jsx"></span>
<span id="exemple-de-srccomponentscoordxy.jsx"></span>
===  <code>/src/components/CoordXY.jsx</code> ===


=== Exemple de <code>/src/components/CoordXY.jsx</code> ===
<syntaxhighlight lang="jsx" line copy>import React from 'react';
 
<syntaxhighlight lang="js" line copy>import React from 'react';
import ZoneTexte from './ZoneTexte';
import ZoneTexte from './ZoneTexte';


Ligne 175 : Ligne 140 :
export default CoordXY;</syntaxhighlight>
export default CoordXY;</syntaxhighlight>
<span id="exemple-de-srccomponentsgeoloc.jsx"></span>
<span id="exemple-de-srccomponentsgeoloc.jsx"></span>
=== Exemple de <code>/src/components/Geoloc.jsx</code> ===
=== <code>/src/components/Geoloc.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React, { useState } from 'react';
<syntaxhighlight lang="jsx" line copy>import React, { useState } from 'react';
import CoordXY from './CoordXY';
import CoordXY from './CoordXY';


Ligne 201 : Ligne 166 :
export default Geoloc;</syntaxhighlight>
export default Geoloc;</syntaxhighlight>
<span id="exemple-de-srccomponentsetage.jsx"></span>
<span id="exemple-de-srccomponentsetage.jsx"></span>
=== Exemple de <code>/src/components/Etage.jsx</code> ===
=== <code>/src/components/Etage.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneTexte from './ZoneTexte';
import ZoneTexte from './ZoneTexte';


Ligne 212 : Ligne 177 :
export default Etage;</syntaxhighlight>
export default Etage;</syntaxhighlight>
<span id="exemple-de-srccomponentscodeacces.jsx"></span>
<span id="exemple-de-srccomponentscodeacces.jsx"></span>
=== Exemple de <code>/src/components/CodeAcces.jsx</code> ===
=== <code>/src/components/CodeAcces.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneNumerique from './ZoneNumerique';
import ZoneNumerique from './ZoneNumerique';


Ligne 223 : Ligne 188 :
export default CodeAcces;</syntaxhighlight>
export default CodeAcces;</syntaxhighlight>
<span id="exemple-de-srccomponentscodepos.jsx"></span>
<span id="exemple-de-srccomponentscodepos.jsx"></span>
=== Exemple de <code>/src/components/CodePos.jsx</code> ===
=== <code>/src/components/CodePos.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneNumerique from './ZoneNumerique';
import ZoneNumerique from './ZoneNumerique';


Ligne 234 : Ligne 199 :
export default CodePos;</syntaxhighlight>
export default CodePos;</syntaxhighlight>
<span id="exemple-de-srccomponentsville.jsx"></span>
<span id="exemple-de-srccomponentsville.jsx"></span>
=== Exemple de <code>/src/components/Ville.jsx</code> ===
=== <code>/src/components/Ville.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneTexte from './ZoneTexte';
import ZoneTexte from './ZoneTexte';


Ligne 245 : Ligne 210 :
export default Ville;</syntaxhighlight>
export default Ville;</syntaxhighlight>
<span id="exemple-de-srccomponentsadresse.jsx"></span>
<span id="exemple-de-srccomponentsadresse.jsx"></span>
=== Exemple de <code>/src/components/Adresse.jsx</code> ===
=== <code>/src/components/Adresse.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React, { useState } from 'react';
<syntaxhighlight lang="jsx" line copy>import React, { useState } from 'react';
import Etage from './Etage';
import Etage from './Etage';
import CodeAcces from './CodeAcces';
import CodeAcces from './CodeAcces';
Ligne 265 : Ligne 230 :
       <CodeAcces value={codeAcces} onChange={(e) => setCodeAcces(e.target.value)} />
       <CodeAcces value={codeAcces} onChange={(e) => setCodeAcces(e.target.value)} />
       <CodePos value={codePos} onChange={(e) => setCodePos(e.target.value)} />
       <CodePos value={codePos} onChange={(e) => setCodePos(e.target.value)} />
       {codePos &amp;&amp; <Ville value={ville} onChange={(e) => setVille(e.target.value)} />}
       {codePos && <Ville value={ville} onChange={(e) => setVille(e.target.value)} />}
       <Zone />
       <Zone />
     </div>
     </div>
Ligne 272 : Ligne 237 :


export default Adresse;</syntaxhighlight>
export default Adresse;</syntaxhighlight>
==== Explication ====
* '''Condition <code>{codePos &amp;&amp; <Ville ... />}</code>''' : Cette ligne signifie que le composant <code>Ville</code> ne sera rendu que si <code>codePos</code> a une valeur non vide. Si <code>codePos</code> est une chaîne vide (<code>''</code>), alors le composant <code>Ville</code> ne sera pas affiché.
* '''Gestion de l’État''' : Lorsque l’utilisateur saisit quelque chose dans le champ <code>CodePos</code>, l’état <code>codePos</code> est mis à jour, ce qui déclenche un re-rendu du composant <code>Adresse</code>. Si <code>codePos</code> a une valeur, le composant <code>Ville</code> est alors affiché.
Cette approche permet de s’assurer que le champ de la ville n’est visible que lorsque l’utilisateur a saisi un code postal, ce qui peut être utile pour des raisons de logique métier ou d’expérience utilisateur.
<span id="exemple-de-srccomponentszone.jsx"></span>
<span id="exemple-de-srccomponentszone.jsx"></span>
=== Exemple de <code>/src/components/Zone.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
===  <code>/src/components/Zone.jsx</code> ===
 
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import RueToureP from './RueToureP';
import RueToureP from './RueToureP';
import Tou from './Tou';
import Tou from './Tou';
Ligne 301 : Ligne 275 :
export default Zone;</syntaxhighlight>
export default Zone;</syntaxhighlight>
<span id="exemple-de-srccomponentsruetourep.jsx"></span>
<span id="exemple-de-srccomponentsruetourep.jsx"></span>
=== Exemple de <code>/src/components/RueToureP.jsx</code> ===
=== <code>/src/components/RueToureP.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneNumerique from './ZoneNumerique';
import ZoneNumerique from './ZoneNumerique';


Ligne 312 : Ligne 286 :
export default RueToureP;</syntaxhighlight>
export default RueToureP;</syntaxhighlight>
<span id="exemple-de-srccomponentstou.jsx"></span>
<span id="exemple-de-srccomponentstou.jsx"></span>
=== Exemple de <code>/src/components/Tou.jsx</code> ===
=== <code>/src/components/Tou.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneNumerique from './ZoneNumerique';
import ZoneNumerique from './ZoneNumerique';


Ligne 323 : Ligne 297 :
export default Tou;</syntaxhighlight>
export default Tou;</syntaxhighlight>
<span id="exemple-de-srccomponentsrep.jsx"></span>
<span id="exemple-de-srccomponentsrep.jsx"></span>
=== Exemple de <code>/src/components/Rep.jsx</code> ===
=== <code>/src/components/Rep.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneNumerique from './ZoneNumerique';
import ZoneNumerique from './ZoneNumerique';


Ligne 334 : Ligne 308 :
export default Rep;</syntaxhighlight>
export default Rep;</syntaxhighlight>
<span id="exemple-de-srccomponentsetablissement.jsx"></span>
<span id="exemple-de-srccomponentsetablissement.jsx"></span>
=== Exemple de <code>/src/components/Etablissement.jsx</code> ===
=== <code>/src/components/Etablissement.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ZoneNumerique from './ZoneNumerique';
import ZoneNumerique from './ZoneNumerique';


Ligne 345 : Ligne 319 :
export default Etablissement;</syntaxhighlight>
export default Etablissement;</syntaxhighlight>
<span id="exemple-de-srccomponentsformadresse.jsx"></span>
<span id="exemple-de-srccomponentsformadresse.jsx"></span>
=== Exemple de <code>/src/components/FormAdresse.jsx</code> ===
=== <code>/src/components/FormAdresse.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import Adresse from './Adresse';
import Adresse from './Adresse';


Ligne 360 : Ligne 334 :
export default FormAdresse;</syntaxhighlight>
export default FormAdresse;</syntaxhighlight>
<span id="exemple-de-srccomponentspage.jsx"></span>
<span id="exemple-de-srccomponentspage.jsx"></span>
=== Exemple de <code>/src/components/Page.jsx</code> ===
=== <code>/src/components/Page.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import FormAdresse from './FormAdresse';
import FormAdresse from './FormAdresse';
import Bouton from './Bouton';
import Bouton from './Bouton';
Ligne 375 : Ligne 349 :
     <div>
     <div>
       <FormAdresse />
       <FormAdresse />
       <Bouton valeur=&quot;Enregistrer&quot; etat=&quot;activer&quot; onClick={handleSave} />
       <Bouton valeur="Enregistrer" etat="activer" onClick={handleSave} />
     </div>
     </div>
   );
   );
Ligne 382 : Ligne 356 :
export default Page;</syntaxhighlight>
export default Page;</syntaxhighlight>
<span id="exemple-de-srccomponentsapplication.jsx"></span>
<span id="exemple-de-srccomponentsapplication.jsx"></span>
=== Exemple de <code>/src/components/Application.jsx</code> ===
=== <code>/src/components/Application.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import Page from './Page';
import Page from './Page';


Ligne 397 : Ligne 371 :
export default Application;</syntaxhighlight>
export default Application;</syntaxhighlight>
<span id="exemple-de-srcapp.jsx"></span>
<span id="exemple-de-srcapp.jsx"></span>
=== Exemple de <code>/src/App.jsx</code> ===
=== <code>/src/App.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import Application from './components/Application';
import Application from './components/Application';


const App = () => {
const App = () => {
   return (
   return (
     <div className=&quot;App&quot;>
     <div className="App">
       <Application />
       <Application />
     </div>
     </div>
Ligne 412 : Ligne 386 :
export default App;</syntaxhighlight>
export default App;</syntaxhighlight>
<span id="exemple-de-srcindex.jsx"></span>
<span id="exemple-de-srcindex.jsx"></span>
=== Exemple de <code>/src/index.jsx</code> ===
=== <code>/src/index.jsx</code> ===


<syntaxhighlight lang="js" line copy>import React from 'react';
<syntaxhighlight lang="jsx" line copy>import React from 'react';
import ReactDOM from 'react-dom';
import ReactDOM from 'react-dom';
import App from './App';
import App from './App';
Ligne 426 : Ligne 400 :
Cette structure vous permet de gérer l’état local de chaque composant et de conditionner l’affichage de la ville en fonction de la saisie du code postal. Chaque composant est responsable de sa propre logique et de son rendu, ce qui facilite la maintenance et l’évolution de l’application.
Cette structure vous permet de gérer l’état local de chaque composant et de conditionner l’affichage de la ville en fonction de la saisie du code postal. Chaque composant est responsable de sa propre logique et de son rendu, ce qui facilite la maintenance et l’évolution de l’application.


==== '''B. Composants Contextuels (Réactivité Conditionnelle)''' ====
== '''2.Exemple Ville from CodPos''' ==


<syntaxhighlight lang="jsx" line copy>// components/formadresse/Ville.jsx
Pour créer un composant <code>Ville</code> qui affiche une liste de villes provenant d’une API fictive et qui se base sur le <code>codePos</code> pour sélectionner la bonne ville, nous allons suivre les étapes suivantes :
export const Ville = ({ codePostal }) => {
  const [ville, setVille] = useState("");


  // Effet réactif : Chargement de la ville basé sur le code postal
# '''Simuler une API''' : Nous allons simuler une API qui renvoie une liste de villes en fonction du <code>codePos</code>.
  useEffect(() => {
# '''Composant <code>Ville</code>''' : Ce composant va récupérer les villes en fonction du <code>codePos</code> et afficher une liste déroulante (<code>select</code>) des villes correspondantes.
    if (codePostal) {
# '''Mécanisme de Sélection''' : Lorsque le <code>codePos</code> change, le composant <code>Ville</code> va mettre à jour la liste des villes.
      // Simule un appel API (ex: fetch(`/api/villes?cp=${codePostal}`))
      setVille("Paris"); // Valeur mockée
    }
  }, [codePostal]); // Dépendance réactive


  return <ZoneTexte value={ville} onChange={setVille} />;
Voici comment vous pourriez structurer cela :
};
};</syntaxhighlight>


-----
<span id="simulation-de-lapi"></span>


<span id="c.-gestion-détat-global-contexte-ou-redux"></span>
=== Simulation de l’API ===
==== '''C. Gestion d’État Global (Contexte ou Redux)''' ====


<syntaxhighlight lang="jsx" line copy>// contexts/AdresseContext.jsx
Nous allons créer une fonction qui simule un appel API pour récupérer les villes en fonction du <code>codePos</code>.
import { createContext, useState } from 'react';


export const AdresseContext = createContext();
<syntaxhighlight lang="jsx" line copy>// Simuler un appel API
const fetchVillesByCodePos = async (codePos) => {
  // Simuler des données fictives
  const villesData = {
    '75001': ['Paris 1'],
    '75002': ['Paris 2'],
    '69001': ['Lyon 1'],
    '69002': ['Lyon 2'],
    // Ajoutez d'autres codes postaux et villes fictives ici
  };


export const AdresseProvider = ({ children }) => {
  // Simuler un délai de réponse de l'API
  const [adresse, setAdresse] = useState({
  return new Promise((resolve) => {
     codePostal: "",
    setTimeout(() => {
    ville: "",
      resolve(villesData[codePos] || []);
    etage: "",
     }, 500);
    // ... autres champs
   });
   });
};</syntaxhighlight>
<span id="composant-ville"></span>
=== Composant <code>Ville</code> ===


  return (
Le composant <code>Ville</code> va utiliser le hook <code>useEffect</code> pour appeler la fonction <code>fetchVillesByCodePos</code> chaque fois que le <code>codePos</code> change.
    <AdresseContext.Provider value={{ adresse, setAdresse }}>
      {children}
    </AdresseContext.Provider>
  );
};
};</syntaxhighlight>


-----
<syntaxhighlight lang="jsx" line copy>import React, { useState, useEffect } from 'react';


<span id="d.-composant-principal-application"></span>
const Ville = ({ codePos }) => {
==== '''D. Composant Principal (<code>Application</code>)''' ====
  const [villes, setVilles] = useState([]);
  const [selectedVille, setSelectedVille] = useState('');


<syntaxhighlight lang="jsx" line copy>// pages/Application.jsx
  useEffect(() => {
import { AdresseProvider } from '../contexts/AdresseContext';
    const fetchVilles = async () => {
import { FormAdresse } from '../components/formadresse/FormAdresse';
      if (codePos) {
import { Bouton } from '../components/common/Bouton';
        const villes = await fetchVillesByCodePos(codePos);
        setVilles(villes);
        setSelectedVille(villes[0] || '');
      }
    };


export const Application = () => {
    fetchVilles();
   const [isFormValid, setIsFormValid] = useState(false);
   }, [codePos]);


   // Logique de validation réactive (ex: vérifie si tous les champs sont remplis)
   const handleVilleChange = (e) => {
  useEffect(() => {
     setSelectedVille(e.target.value);
     // Implémentez la validation ici
   };
    setIsFormValid(true); // Mock
   }, []); // Dépendances à ajuster


   return (
   return (
     <AdresseProvider>
     <div>
       <FormAdresse />
       {villes.length > 0 ? (
      <Bouton
        <select value={selectedVille} onChange={handleVilleChange}>
        label="Enregistrer"
          {villes.map((ville, index) => (
        disabled={!isFormValid} // Désactivé si le formulaire est invalide
            <option key={index} value={ville}>
        onClick={() => console.log("Sauvegarde...")}
              {ville}
       />
            </option>
     </AdresseProvider>
          ))}
        </select>
       ) : (
        <p>Aucune ville trouvée pour ce code postal.</p>
      )}
     </div>
   );
   );
};
};
};</syntaxhighlight>


-----
export default Ville;</syntaxhighlight>
<span id="intégration-dans-le-composant-adresse"></span>
=== Intégration dans le Composant <code>Adresse</code> ===


<span id="points-stratégiques-de-réactivité"></span>
Enfin, nous allons intégrer le composant <code>Ville</code> dans le composant <code>Adresse</code> et passer le <code>codePos</code> comme prop.
=== '''3. Points Stratégiques de Réactivité''' ===


# '''État Local vs Global'''
<syntaxhighlight lang="jsx" line copy>import React, { useState } from 'react';
#* <code>ZoneNumerique</code>/<code>ZoneTexte</code> : État local si isolé.<br />
import Etage from './Etage';
import CodeAcces from './CodeAcces';
import CodePos from './CodePos';
import Ville from './Ville';
import Zone from './Zone';


#* <code>Ville</code> : Dépend d’un état parent (<code>codePostal</code>) → '''Effet réactif'''.<br />
const Adresse = () => {
  const [etage, setEtage] = useState('');
  const [codeAcces, setCodeAcces] = useState('');
  const [codePos, setCodePos] = useState('');


#* <code>Bouton</code> : Désactivé conditionnellement (<code>isFormValid</code>).
  return (
# '''Effets de Bord'''
    <div>
#* Chargement de la ville après un changement de code postal (<code>useEffect</code>).
      <Etage value={etage} onChange={(e) => setEtage(e.target.value)} />
# '''Optimisation'''
      <CodeAcces value={codeAcces} onChange={(e) => setCodeAcces(e.target.value)} />
#* Mémoisation des composants (<code>React.memo</code>) si re-rendus fréquents.<br />
      <CodePos value={codePos} onChange={(e) => setCodePos(e.target.value)} />
 
      {codePos && <Ville codePos={codePos} />}
#* Éviter les props inutiles qui déclenchent des re-rendus.
      <Zone />
# '''Validation Réactive'''
    </div>
#* Un custom hook comme <code>useFormValidation</code> pourrait surveiller les changements de l’état global.
  );
 
};
 
-----
 
<span id="exemple-de-flux-réactif"></span>
=== '''4. Exemple de Flux Réactif''' ===
 
* L’utilisateur remplit <code>CodePos</code> → '''déclenche''' un effet dans <code>Ville</code>.<br />
 
* La modification de <code>ville</code> met à jour l’état global → '''notifie''' le bouton “Enregistrer”.<br />
 
* Si tous les champs sont valides, le bouton passe en <code>disabled={false}</code>.
 
 
-----
 
<span id="pour-aller-plus-loin"></span>
=== '''5. Pour Aller Plus Loin''' ===
 
* '''Librairies utiles''' :
** <code>react-hook-form</code> pour la gestion de formulaires complexes.<br />
 
** <code>react-query</code> pour les appels API réactifs.<br />
 
* '''Tests''' : Vérifiez les performances avec <code>React DevTools Profiler</code>.


export default Adresse;</syntaxhighlight>
<span id="explication"></span>
=== Explication ===


-----
* '''Appel API Simulé''' : La fonction <code>fetchVillesByCodePos</code> simule un appel API et renvoie une liste de villes en fonction du <code>codePos</code>.
* '''Hook <code>useEffect</code>''' : Le composant <code>Ville</code> utilise <code>useEffect</code> pour appeler la fonction <code>fetchVillesByCodePos</code> chaque fois que le <code>codePos</code> change.
* '''Liste Déroulante''' : Le composant <code>Ville</code> affiche une liste déroulante (<code>select</code>) des villes correspondantes au <code>codePos</code>. Si aucune ville n’est trouvée, un message est affiché.


Cette architecture sépare clairement :<br />
Cette approche permet de sélectionner dynamiquement les villes en fonction du code postal saisi par l’utilisateur.
- Les '''composants UI''' (stateless si possible).<br />
- La '''logique réactive''' (effets, état).<br />
- Les '''règles métier''' (validation, dépendances).


😊


== Vidéos ==
[https://www.youtube.com/watch?v=1p6TsZW_HDk C'est quoi react (Youtube)]


[[Category:Private]]
[[Category:React]]