# Notre premier composant React Si vous êtes arrivé ici, c'est que vous avez compris ce qu'est un composant React et qu'il est composant de `props` et d'un `state`. Mettons donc en pratique ce que vous avez vu. Voici le cahier de charge fonctionnel du composant à implémenter : Fonction: - On veut ajouter un bouton `Home` dans l'éditeur pour revenir au menu principal Contraintes principales : - Le bouton `home` ne doit pas rafraîchir la page Contraites secondaires : - Le bouton est positionné en bas sur la barre - Le bouton change de couleur à chaque fois que le curseur entre dedans - Le bouton possède un icône home ## Initialiser un composant Commençont par créer le composant sans le lier forcément au reste du projet. Par convention comme il est dit dans la section [Pour commencer](PourCommencer.md), créons le fichier `Home.tsx` dans un dossier `Home/` dans `src/Components`. Il est recommandé de toujours créer un dossier pour le composant pour plus tard si on veut ajouter des styles propres au composant ou si on veut faire des tests. Maintenant créons le squelette du composant. Pour rappel, on utilise la syntaxe *fonctionnelle* (i.e. une fonction = un composant). ```tsx // Home.tsx export function Home(): JSX.Element { return <>; } ``` Note: vous pouvez utiliser le snippet `tsrfc` si vous utilisez l'extension de VSCode. La convention de nommage indique qu'il faut prioriser les fonctions nommées (donc pas de flèches fonctions). Mettons le bouton html et mettons du texte dedans : ```tsx export function Home(): JSX.Element { return ( ); } ``` ## Appeler une fonction Pour que le bouton appelle une fonction nous allons utiliser la propriété `onClick`. Pour lui équiper d'une variable/fonction, on la met entre accolades `prop={var}`. ```tsx function GoHome(): void { location.reload(); } export function Home(): JSX.Element { return ( ); } ``` Cela devrait être suffisant pour revenir au menu principal. Appelons-le dans l'editeur. ## Ajouter le composant dans l'editeur Tout ce qui est UI doit se mettre dans `UI.tsx`. On sait que l'on doit l'ajouter dans la **barre** à gauche, soit `Bar.tsx` Commençons par importer le composant dans `Bar.tsx`: ```tsx // Bar.tsx import { Home } from '../Home/Home'; ... ``` Puis ajoutons-le dans la vue : ```tsx // Bar.tsx export function Bar(props: IBarProps): JSX.Element { return (
...
); } ``` Testez avec `pnpm dev`. Et ouvrez la page sur `http://localhost:5173`. Et voilà ! Vous avez fini ! ... Sauf que vous n'avez respecté aucune des contraintes. Faisons mieux. Utilisons les `props` et le `state` de l'application. ## Props et state Le composant doit restaurer l'état du menu principal. Dans le menu principal, lorsque l'on clique sur `Start from scratch`, le composant doit forcément changer un état pour cacher le menu. Ce que l'on veut faire est donc de renverser cette opération, autrement dit changer l'état qui permet de cacher le menu pour le remontrer. Allons donc dans le composant `MainMenu.tsx` et analysons le contenu du bouton `Start from scratch`. ```tsx // MainMenu.tsx ... default: return (
); ``` On trouve la fonction `onClick` suivante : ```tsx // MainMenu.tsx ); } ``` Note: vous pouvez utiliser `Home(props: IHomeProps)` et appeler `props.goHome` comme tout le reste du projet au lieu de le destructurer en `{ goHome }`, mais le destructuring d'objet est autorisé (et dans certains cas, c'est mieux avec). Home est utilisé dans les composants Bar, UI, et Editor avant d'être appelé dans App. Il faut faire la même chose, ajouter la fonction dans les props et l'appeler dans le composant : ```tsx // Bar.tsx interface IBarProps { goHome: () => void } ... export function Bar(props: IBarProps): JSX.Element { return (
...
); } ``` *Faites la même chose pour UI et Editor.* Enfin dans `App.tsx`, créez la fonction permettant de changer `appState` vers `AppState.MainMenu`: ```tsx ... case AppState.Loaded: return (
setAppState(AppState.MainMenu)} />
); ... ``` Félicitation vous avez correctement développé votre premier composant Home ! Essayons maintenant de faire le reste dans le prochain chapitre avec [`TailwindCSS`](Tailwind.md)