Transcription
1. Introduction: Bonjour, je suis Hunor, et aujourd'hui je vais vous
apprendre à construire un jeu Tic-Tac-Toe avec React. Si vous n'avez pas utilisé React auparavant, ne vous inquiétez pas, nous allons couvrir toutes les bases de React pendant que nous construisons ce jeu. abord, je vais parler de la façon de décomposer ce jeu en morceaux plus petits, en composants, et comment connecter ces composants. Ensuite, nous allons couvrir comment rendre ce jeu interactif, quel est l'état, et comment détecter le gagnant à la fin du jeu. La seule chose que vous devez avoir est une connaissance préalable HTML, CSS et JavaScript, et après ce cours, vous serez en mesure de construire un jeu simple ou un site Web avec React.
2. Décomposer le jeu en composants: Nous allons créer notre application dans React. React est une bibliothèque basée sur des composants. Donc, d'abord, nous devons décomposer notre application en composants. Mais qu'est-ce qu'un composant et comment décomposer une application ? Un composant est comme une fonction. Si vous y pensez, vous écrivez principalement des fonctions pour deux raisons. L' une consiste à décomposer votre logique d'application en petits bits significatifs. Une fonction est fondamentalement un morceau de code avec un nom. Si quelqu'un lit ce nom, espérons-le, il saura ou au moins aura une bonne idée de ce que fait la fonction. La deuxième raison pour écrire une fonction est d'éviter la répétition. Si vous vous trouvez à écrire les mêmes lignes encore et encore, alors vous allez probablement écrire une fonction pour
cela et l'appeler à plusieurs endroits au lieu de répéter les mêmes lignes. Nous allons faire la même chose avec les composants. Mais avant d'y arriver, abord, nous avons besoin d'un composant initial celui qui sera injecté dans HTML et qui servira de racine pour tout le reste de l'application. Dans notre cas, ce sera le composant TicTactoe lui-même. Techniquement, on peut s'arrêter ici. Il n'est pas nécessaire d'avoir plusieurs composants. Mais généralement, si vous essayez d'avoir toute votre logique dans un composant avec toutes les informations de mise en page, probablement, cela va être trop long et inmaintenable. Commençons donc à décomposer notre application en évitant les répétitions. Il y a deux choses très évidemment répétées dans cette application, les croix et les cercles. Il y a aussi un troisième, qui n'est pas si visuel, donc c'est facile à manquer. Mais si vous regardez un peu plus près, alors vous voyez que cette grille se compose de neuf carrés. Et les carrés n'ont pas grand-chose à montrer, mais vous allez voir que leur comportement est le même. Ils vont donc aussi être un très bon candidat pour un composant. Une fois que nous avons terminé avec la répétition, nous pouvons rechercher des parties de l'application qui sont plus ou moins indépendantes du reste de l'application. Dans notre cas, si vous jouez à travers ce jeu, alors vous vous retrouvez sur un écran de résultats. Bien sûr, cet écran de résultat n'est pas entièrement indépendant du reste
du jeu car il doit savoir si le jeu est terminé,
qui a gagné le jeu et comment réinitialiser le jeu. Mais à part cela, il n'a pas besoin de connaître tous les détails. Il n'a pas besoin de savoir quel est le statut du deuxième carré de la troisième rangée. Donc de cette façon, c'est indépendant. Il pourrait être interprété comme une fonction avec des propriétés. Ce seront donc nos composants,
mais bien sûr, ce n'est pas le seul moyen de décomposer une application. Une façon de vérifier si nous avons fait un bon travail est de vérifier les noms des composants. Si les noms des composants sont significatifs et que vous pouvez plus ou moins deviner ce que fait le composant ou à quoi il ressemble, il y a de fortes chances que notre ventilation soit bonne.
3. Écrire nos premiers composants: Commençons à créer des choses. Pour ce tutoriel, nous allons utiliser CodePen, qui est un éditeur web et une plateforme de médias sociaux. Lorsque vous créez quelque chose sur CodePen, il sera public afin que d'autres personnes puissent le voir, peuvent le commenter, peuvent l'aimer, et si c'est vraiment bon et que les éditeurs des sites le voient, alors peut-être qu'ils le mettent en évidence et vous pouvez vous voir sur la première page. Si vous n'avez pas utilisé CodePen auparavant, vous pouvez simplement vous inscrire rapidement en utilisant votre compte Twitter, GitHub ou Facebook. Une fois que vous êtes dans, dans le coin supérieur gauche, vous verrez « Créer un stylo », ce qui nous mène à l'éditeur Web. Donc, c'est votre éditeur ici, vous pouvez éditer HTML, CSS et JavaScript et la chose géniale à ce sujet est une fois que vous modifiez quelque chose, puis le résultat apparaîtra dans l'écran des résultats tout de suite. Si vous ajoutez un simple en-tête primaire et un paragraphe, vous verrez le résultat dans le panneau de résultats. Nous allons utiliser React et React ne fait pas partie du JavaScript standard. C' est une bibliothèque externe. Heureusement pour nous, dans CodePen, vous pouvez facilement ajouter des bibliothèques externes à un projet. Accédez à Paramètres, sélectionnez le panneau JavaScript et recherchez Réagir. Une fois que vous avez ajouté React, nous devons également ajouter quelque chose appelé ReactDom et ici vous devez faire
attention à ce que le numéro de version de React et le numéro de version de ReactDom doivent correspondre. Si ce n'est pas le cas pour certaines raisons, alors consultez le commentaire ci-dessous cette vidéo. Nous devons mettre une chose de plus ici. Nous devons définir un préprocesseur JavaScript et ce sera Babel dans notre cas. En ce qui concerne ce qui est Babel, pourquoi avons-nous besoin et ce qui est ReactDom. Je vais l'expliquer dans un peu, mais pour l'instant, gardons ça et nous sommes prêts à partir. Écrivons du JavaScript et commençons par créer notre tout premier composant. Et cela peut être surprenant, mais un composant est fondamentalement une fonction. Quand je disais auparavant que la façon dont vous décomposer une application à un composant est la même que de décomposer une logique d'application en fonctions. Eh bien, les composants sont plus proches des fonctions que vous auriez pu le penser. Un composant est une fonction spéciale qui renvoie quelque chose qui ressemble vraiment au HTML. Mais ce n'est toujours pas HTML, nous sommes toujours à l'intérieur de JavaScript et vous pourriez vous demander comment cela fonctionne ? Je veux dire, ce n'est pas JavaScript. Vous ne pouvez pas ajouter de balises HTML en JavaScript, et la réponse à cette question est qu'en fait, nous n'utilisons pas JavaScript ici. Ce n'est pas JavaScript. Au moins pas pur JavaScript. Rappelez-vous que nous avons défini Babel comme un préprocesseur pour JavaScript. Babel est en train de transpiler ce code en JavaScript approprié. En arrière-plan, nous avons JavaScript correct, mais nous éditons une version légèrement modifiée de JavaScript, ce qui nous permet d'écrire des balises HTML. Ou au moins quelque chose qui ressemble vraiment à des balises HTML. Nous avons un composant React, mais dans l'écran des résultats, nous ne le voyons toujours pas. C' est comme avoir une fonction qui n'a jamais été appelée. Nous avons une fonction qui génère un morceau de HTML, mais nous ne disons pas où ce HTML généré devrait appartenir et il n'est pas ajouté automatiquement à la racine du HTML. Nous devons définir un point d'entrée en HTML. Ajoutons simplement un div simple, avec un ID, et je vais utiliser « app » comme ID, mais vous pouvez simplement écrire n'importe quel autre nom si vous voulez. En JavaScript, nous allons utiliser ReactDom. ReactDom est une bibliothèque utilitaire très simple et son seul but est de rechercher le code HTML, trouver cet identifiant et de remplacer son contenu par notre composant. Si vous avez tout fait correctement, alors enfin, nous avons un composant React dans notre site Web et c'est un très bon début. Avant de passer à la section suivante, ajoutons rapidement le squelette des autres composants sur lesquels nous avons convenu. Ajoutons simplement un composant Square, un composant Cross
et le composant Circle ainsi que les composants de l'écran de résultats. Ces composants pour l'instant vont être des composants très simples. Ils retournent juste un morceau de texte et ils ne seront pas connectés à nos composants racine. Ils restent juste dans l'espace et ne font rien du tout, mais c'est notre squelette d'application. Nous allons connecter ces composants dans nos prochaines sections.
4. La grille: Dans nos leçons précédentes, nous avons écrit nos tout premiers composants React. Mais sur notre écran de résultats, nous ne voyons toujours « Hello from React » que dans le coin supérieur gauche, et nous n'utilisons même pas du tout la plupart de nos composants React. Dans cette leçon, nous allons parler beaucoup de CSS, comment ajouter du style à ces composants, et comment les connecter, comment intégrer le composant Square à l'intérieur du composant TicTactoe. Tout d'abord, centrons tout. En ce moment, par défaut, tout est dans le coin supérieur gauche. Et c'est un jeu, ce n'est pas un site Web normal, nous voulons tout centrer. Pour centrer tout, nous allons à notre balise de niveau le plus élevé et définissons quelques propriétés CSS pour cela. Le niveau le plus élevé en ce moment est notre div à l'intérieur du HTML, qui est le point d'entrée de l'application. Il a déjà un ID, donc laissez-nous simplement l'utiliser dans CSS, et pour centrer les choses, nous allons utiliser CSS Flexbox. Si vous n'avez pas utilisé CSS Flexbox auparavant, c'est vraiment bon pour centrer les choses et aligner les choses uniformément. moment, nous allons seulement l'utiliser pour le centrage, et il a des noms de propriétés vraiment bizarres comme justify-content et align-items. Ce n'est pas si intuitif que l'on est pour aligner les choses horizontalement et l'on est pour aligner les choses verticalement, mais cela fonctionne vraiment bien. Une fois que nous l'avons ajouté, tout devrait être au milieu de l'écran. Eh bien, tout en ce moment est juste un texte disant, « Bonjour de React », parce que c'est tout ce que produit le composant TicTactoe. Changeons ça. Remplaçons ce texte initial par neuf instances du composant Square. Vous vous demandez peut-être comment le faire parce que, composant
TicTactoe produit un morceau de HTML, composant
Square produit également un morceau de HTML, mais le composant Square lui-même est juste une fonction. Alors faisons-nous des appels de fonction, et appelons-nous les composants Square comme une fonction ? Dans React, vous pouvez faire référence à des composants, comme s'il s'agissait de balises HTML personnalisées. Ce qui est vraiment pratique car le composant Square est nécessaire dans l'instruction return d'un composant TicTactoe. Maintenant, nous avons neuf carrés dans le composant TicTactoe, mais ils n'apparaissent pas sous forme de grille. Pour corriger cela, nous allons attribuer une classe CSS pour le conteneur principal du composant TicTactoe. Et c'est quelque chose qui est légèrement différent du HTML. Comme je l'ai dit précédemment, ce n'est pas HTML en fait, il ressemble juste à ça. Ceci est appelé JSX, JavaScript XML, et il a quelques différences mineures par rapport au HTML. L' un d'eux est que vous ne pouvez pas utiliser le mot-clé class, car le mot-clé class est réservé en JavaScript et a des significations très différentes. Au lieu d'écrire la classe, nous écrivons ClassName. Pour aligner le contenu dans une grille, nous allons utiliser la grille CSS. Si vous n'avez pas utilisé la grille CSS avant ou CSS Flexbox, il y a un lien en dessous de cette vidéo qui explique vraiment bien comment ils fonctionnent. Donc, avec la grille CSS, nous définissons, que nous voulons avoir trois colonnes et trois lignes, et nous voulons avoir un écart entre eux. Maintenant, ça a l'air un peu mieux, mais les carrés ne ressemblent pas du tout à des carrés. la même manière que nous avons attaché une classe pour le composant TicTactoe, attachons une classe carrée pour le composant Square, et ajoutons du CSS. Ici, nous fixons la largeur, et la hauteur du composant, sorte qu'il ressemblera à un carré, et nous centrons également le contenu du carré de la même manière que nous avons centré l'ensemble de l'application, qui CSS Flexbox. Maintenant, nous avons nos neuf carrés dans une grille, mais nous voulons avoir une frontière entre eux. Malheureusement, avec la grille CSS, nous ne pouvons pas définir la couleur de bordure. Nous allons utiliser un petit tour ici. Au lieu de définir la couleur de bordure, nous définissons la couleur d'arrière-plan de toute la grille, puis définissons la couleur d'
arrière-plan des composants carrés sur la couleur d'arrière-plan de l'application entière. De cette façon, il semble que nous avons défini la couleur de bordure de la grille, même si nous ne l'avons pas fait.
5. Quel carré is ?: Nous avons notre belle grille, mais tous les carrés à l'intérieur ressemblent. Juste pour clarifier, quel carré est lequel, donnons-leur un ID unique. Dans React, vous pouvez configurer des instances de composant en leur transmettant des accessoires. Un accessoire est quelque chose comme un attribut à une fonction. Nous allons dire que c'est exactement un attribut pour notre fonction de composant. Définissons un attribut de position pour chacune de nos instances de composant. Dans React, vous pouvez transmettre une propriété de la même manière que vous définiriez un attribut pour une balise HTML. Nous pouvons écrire des positions égales et nous passons « 0". Nous allons utiliser l'index de base zéro ici, car plus tard, lorsque nous spécifions une valeur appropriée pour les carrés, nous allons également utiliser l'index de base zéro. Nous pouvons également transmettre une valeur d'une manière un peu différente. Au lieu d'utiliser des guillemets doubles ici, nous pouvons également utiliser des crochets bouclés. En utilisant des crochets bouclés ici, est appelé liaison. C' est un moyen beaucoup plus puissant de passer certaines propriétés pour les composants enfants. Avec des crochets bouclés, nous ouvrons essentiellement une fenêtre pour JavaScript. Initialement, nous sommes en terre JavaScript, mais ensuite avec JSX nous commençons à écrire du HTML. Mais que faire si vous voulez revenir à JavaScript dans HTML ? Ensuite, nous utilisons la liaison, avec des crochets bouclés, nous ouvrons une fenêtre à JavaScript, et tout ce qui est à l'intérieur de ces crochets bouclés est évalué comme une expression JavaScript et le résultat de cela sera transmis comme une propriété. heure actuelle, nous n'utilisons pas tout son pouvoir parce que nous ne faisons que transmettre un nombre. Mais nous pourrions aussi utiliser un calcul mathématique ici, nous pourrions appeler une fonction ici, avoir une expression ternaire... Tout ce qui est une expression JavaScript valide, nous pouvons utiliser ici. Il y a aussi une différence mineure ici entre la transmission d'une valeur entre crochets bouclés et la transmission d'une valeur entre guillemets doubles. Si vous passez un nombre entre guillemets doubles, ce sera un texte, il sera interprété comme une chaîne. D' un autre côté, si vous passez un nombre entre crochets bouclés, il va rester un nombre. Allons de l'autre côté des choses et utilisons cette propriété transmise dans le composant Square. Comme je l'ai dit, les propriétés dans les composants
React sont transmises en tant qu'attribut pour la fonction de composant. Mais au lieu que le premier attribut de cette fonction devienne simplement position, le premier attribut nous serons un objet générique pour toutes les propriétés du composant. Cela peut être déroutant pour les composants qui n'ont qu'une seule propriété. Sachez que le premier attribut va toujours être un objet, qui a un attribut en ce moment, la position. Ici, nous pouvons attraper l'objet props entier et se référer à l'attribut de position de l'objet props, ou nous pouvons décomposer cet objet props tout de suite dans la signature de la fonction. Nous avons cet attribut de position maintenant, transmis. Comment l'utilisons-nous ? Fondamentalement, ce que nous voulons atteindre est au lieu de montrer « Square », nous voulons montrer le numéro de position à l'intérieur de ce composant. Que pouvons-nous faire dans ce cas ? Nous voulons utiliser une variable JavaScript à l'intérieur de JSX. Nous pouvons faire la même chose à nouveau, ce que nous venons de faire avant avec la transmission d'une variable en tant que propriété. Nous pouvons utiliser la liaison. Encore une fois, nous utilisons des crochets bouclés et à l'intérieur des crochets bouclés nous utilisons simplement la variable de position. Après avoir fait tout cela, nous devrions voir un identifiant unique à l'intérieur de chaque carré, à l'intérieur de notre grille.
6. Les parties changeantes: Dans notre leçon précédente, nous avons réussi à transmettre une pièce d'identité unique pour chaque carré, mais à
l'intérieur des carrés, nous voulons plutôt avoir des cercles sur des croix en fonction de la progression du jeu. C' est quelque chose qui va être dynamique. Au départ, chaque carré va être vide et une fois que vous cliquez dessus, il devrait montrer un cercle ou une croix. Dans React tout ce qui est dynamique, tout ce qui change au fil du temps doit être défini dans un état. L' état avec les accessoires sont les deux principaux facteurs qui façonnent un composant, mais tandis que les accessoires sont transmis par
les parents afin qu'ils sortent du composant, l'état est une chose interne. Qu' est-ce qui change ici ? Il y a deux choses principales qui changent au cours du jeu. À chaque tour, un carré obtient une nouvelle valeur. Il obtient un cercle ou une croix. L' état des carrés est certainement quelque chose dont nous devons garder une trace. L' autre chose qui change au cours du jeu est le joueur. Après chaque tour est en train de changer de cercle à croix ou de croix à cercle. Ce seront les deux parties principales de notre État. Maintenant, nous devrions discuter où définir l'état. En ce qui concerne le joueur, il est logique de le définir au niveau supérieur car cela n'a rien à voir avec les carrés, les cercles ou les croix. C' est l'état du jeu. Mais en ce qui concerne l'état des carrés, il peut sembler logique de les définir au niveau des carrés. Chaque place serait responsable de son propre état interne. Ils sauraient s'ils doivent être vides ou s'ils doivent contenir une croix ou un cercle. Mais il y a un problème architectural majeur avec celui-ci. Les carrés connaîtront leur propre état interne, mais personne ne connaîtrait l'état entier de la grille. C' est à cause de la façon dont la communication fonctionne entre les composants de React. React fonctionne de haut en bas. Un composant de niveau supérieur, comme le composant TicTactoe, peut transmettre des propriétés aux composants de niveau enfant comme le composant Square, mais cela ne fonctionne pas dans l'inverse. Dans le composant Square, les enfants ne peuvent pas transmettre des propriétés à leurs parents. de vue enfant, le composant Square peut avoir accès à l'état du composant TicTactoe car
le composant TicTactoe peut le transmettre en
tant que propriété, mais il ne fonctionne pas dans l'inverse. Le composant TicTactoe ne peut pas avoir accès à l'état du composant Square car le composant Square ne peut tout simplement pas le transmettre. Nous allons voir qu'il y a une solution de contournement ici. Nous pouvons utiliser des rappels pour signaler certains progrès de l'enfant au parent, mais c'est un peu différent. Avec des accessoires, vous passez sur une propriété. Vous exposez certaines de vos variables à vos enfants. Mais avec les rappels, ce sont des appels de fonction. C' est un peu comme un événement. Ce n'est pas comme partager vos variables. Une fois que nous avons compris comment la communication fonctionne entre les composants et comment l'état et les accessoires fonctionnent ensemble, nous pouvons probablement convenir que si vous avez besoin d'une certaine logique, qui est de détecter si le jeu est terminé et vous indique quel joueur gagné le jeu, alors nous avons besoin d'avoir l'état de chaque carré dans un endroit commun. Ce sera un niveau plus élevé dans le composant TicTactoe. Maintenant, nous sommes d'accord que nous allons avoir tout notre état dans le composant de niveau supérieur et c'est un modèle assez commun. Habituellement, les composants de niveau supérieur sont les composants intelligents. Ils ont généralement la logique et l'état mais ils ne sont pas si visuels tandis que d'autre part les composants de niveau inférieur reçoivent généralement toutes leurs valeurs vrais accessoires et ce sont eux qui ont à des représentations
visuelles de la mais l'état en général n'a pas toujours besoin d'être au niveau supérieur. Il doit en fait être aussi bas que possible, mais aussi élevé que nécessaire. Prenons un autre exemple pour cela. Disons que vous êtes vraiment bon dans le développement de jeux et que vous avez créé un site plein de jeux. Il contiendra une application TicTactoe, il contiendra un Tetris ou Mine Sweeper etc. Dans ce cas, si vous avez le composant de niveau supérieur, qui est la page entière, il n'a pas besoin de connaître l'état interne de la Jeu TicTactoe. Nous pouvons toujours avoir des états de niveau inférieur individuellement pour chaque jeu et dans le niveau supérieur, peut-être qu'il n'y a pas d'état du tout.
7. Première tentative d'ajouter un état: Dans la leçon précédente, nous avions beaucoup de théorie sur la façon dont l'état fonctionne et comment les composants de l'application peuvent être connectés avec des accessoires. Commençons à définir notre état. Comme nous l'avons convenu. Passons au composant Tic Tac Toe et définissons un état pour le joueur et pour les positions. Les positions pour l'instant, ce sera un tableau qui contiendra la valeur de chaque carré dans la grille. Mais avant de définir les états, nous allons juste avoir quelques constantes pour les valeurs possibles des carrés. Définissons les états. Pour l'instant, définissons les états comme des variables simples. Plus tard, nous verrons que les états doivent être quelque chose de spécial, autre
chose qu'une simple variable. Mais pour l'instant, gardons les choses simples. Une fois que nous définissons l'état de position qui contient deux valeurs de chaque carré, laissez simplement passer cette valeur pour chaque carré. Nous le faisons simplement de la même manière que nous
transmettons un attribut de position pour le composant. Nous ajoutons un nouvel accessoire ici. Appelons simplement la valeur, qui peut contenir un cercle vide ou une croix. Juste pour rendre cet exemple un peu plus intéressant, au lieu d'avoir une grille vide comme état initial, nous allons juste avoir quelques croix et cercles aléatoires dans cet état. Ok, donc maintenant nous transmettons une valeur pour chaque carré, mais bien sûr, nous devons aussi changer le composant Square pour refléter ces valeurs. Le composant Square doit contenir un cercle ou un composant croisé en fonction de cette valeur. Pour ce faire, nous allons utiliser une expression JavaScript. Cela peut être un peu déroutant au début, mais c'est simplement une opération booléenne. Si la première partie avant le && est false
, la deuxième partie de cette expression n'est pas évaluée. Simplement false est retourné. Mais si la première partie est vraie, alors la deuxième partie sera le résultat de cette expression. Dans ce cas, ce serait un cercle ou une croix. Heureusement pour nous, si une expression est fausse, alors réagissez avec simplement l'ignorer. Dans cette configuration, seul un cercle ou une croix doit apparaître. Jamais les deux et si la valeur est initiale, alors ce carré doit rester vide. Maintenant, dans notre grille, nous devrions déjà voir quelques cercles et croix en
fonction de notre état initial ou du moins le texte réservé pour cela. Mais avant de changer le texte de l'espace réservé en cercles et croix réels,
arrêtons-nous une seconde ici, et réfléchissons à comment cette application fonctionnera.
8. Un état qui peut changer: Avant de passer à autre chose,
arrêtons-nous un peu et voyons comment cette application va fonctionner. Jusqu' à présent, nous avons notre fonction qui génère notre état initial. Après le rendu initial, l'état du jeu changera en fonction de notre interaction. Bien sûr, nous voulons refléter ces changements dans la mise en page. La façon dont React traite cela est en re-rendant le composant entier et il rendra le composant entier en exécutant la même fonction. C' est une situation drôle ici, parce que nous exécutons la même fonction deux fois et nous attendons un résultat différent. J' aime souligner ici que c'est juste une fonction JavaScript normale en dehors de retourner quelque chose qui ressemble au HTML, il n'y a rien de magique ici. Si vous regardez simplement cette fonction, il est assez clair que si vous avez l'état dans ce format, cette fonction va générer le même résultat quel que soit le nombre de fois que nous l'exécutons. Que pouvons-nous faire pour réparer ça ? Nous avons besoin d'un état qui puisse rendre la dernière valeur que nous lui attribuons. Par conséquent, nous devons le stocker en dehors de ce composant. Dans React afin de résoudre ce problème, ils ont introduit React Hooks. L' un des Hooks est appelé USEstate et c'est exactement pour ce problème. Nous le crochet USeState, nous pouvons stocker un état en dehors
du composant et il nous donnera toujours la dernière valeur. La première fois que nous exécutons cette fonction, nous pouvons initialiser l'état avec une valeur que nous transmettons en tant qu'attribut. Cet attribut sera bien sûr ignoré dans tous les appels à venir une fois que la valeur est déjà stockée. Le crochet USeState renvoie un tableau de deux éléments. Le premier élément est l'état lui-même. Si vous exécutez simplement la fonction pour la première fois, alors elle retourne fondamentalement notre état initial. Mais si vous exécutez la fonction en raison d'un re-rendu, alors il retournera la dernière valeur de l'état. Le deuxième élément que le crochet USeState
nous est rendu est une fonction et cette fonction peut être utilisée pour changer l'état. À l'avenir, pour toute interaction, si vous avez besoin de changer l'état, nous devons appeler cette fonction et non seulement nous appelons cette fonction pour changer l'état, mais elle déclenche également automatiquement le re-rendu du composant. Donc, en changeant l'état, nous rendons également le composant,
ce qui, bien sûr, nous reflétons le changement d'état où nous venons d'avoir.
9. Cercles et Cross: Cette leçon va être amusante,
et c'est un œuf de Pâques parce qu'il n'a pas à faire quoi que ce soit qui réagisse. Dans celui-ci, nous allons coder des images. Nous allons dessiner des cercles et des croix à base de vecteurs. Si jamais vous vérifiez le code source d'une image, alors vous réalisez probablement qu'ils sont super compliqués et vous ne pouvez tout simplement rien en sortir. Mais nous allons utiliser les SVG, et les SVG ne sont pas si compliqués, surtout si vous allez simplement l'utiliser pour quelque chose de simple. La bonne chose à propos des SVG est qu'ils sont basés sur XML, et depuis HTML5, ils font partie de la syntaxe HTML. Vous pouvez simplement insérer un SVG dans HTML. Vous n'avez pas besoin d'utiliser une image externe et vous n'avez pas besoin de la charger dans le HTML. Vous pouvez simplement l'écrire dans le cadre de votre HTML. À quoi ressemblent-ils ? Tout d'abord, chaque SVG est enveloppé dans une balise SVG. Dans la balise SVG, vous pouvez définir la largeur et la hauteur du SVG avec la ViewBox. Le ViewBox définit votre repère. Dans notre cas, nous allons définir que le SVG commence le coin supérieur gauche avec la coordonnée -50 -50, et la largeur et la hauteur du SVG Canvas seront 100 chacune. Donc, le centre de l'image sera zéro, zéro. Vous remarquerez peut-être que la hauteur et la largeur que nous avons définies dans SVG et la hauteur et la largeur que nous avons définies dans la ViewBox sont les mêmes mais ce n'est pas quelque chose qui est obligatoire. La hauteur et la largeur définies comme attributs dans la balise SVG seront la taille réelle du SVG. Alors que le ViewBox définit le canevas sur lequel nous pouvons dessiner. Chaque coordonnée à l'intérieur de ce SVG sera liée à ce canevas. La ViewBox définit une taille interne du point de vue des éléments d'image. Si la taille réelle de l'image et la taille définie par la ViewBox ne correspondent pas
, l'image sera simplement réduite ou mise à l'échelle. Maintenant, nous avons une toile. Laissez juste dessiner quelque chose dessus. Commençons par un composant Circle car ce n'est qu'un cercle. Nous pouvons simplement ajouter une balise de cercle et dire que le centre de celui-ci sera
au centre de la toile et le rayon sera de 40 pixels. Vous remarquerez que cela rendra un cercle noir. n'est pas exactement ce que nous voulons, mais puisque les SVG font partie du HTML, nous pouvons également utiliser CSS pour le styliser. Avant le style, définissons simplement le composant Cross. Nous définissons simplement deux lignes en définissant leurs coordonnées de départ et leurs coordonnées de fin. Maintenant, si vous vous demandez, qu'est-ce que vous avez fait de mal parce que vous êtes croix ne se présentent pas, c'est tout à fait normal. Par défaut, la largeur de ligne est égale à zéro. Nous devons changer cela en CSS. Définissons un style pour les SVG en général. Ici, nous pouvons définir une largeur de ligne, qui est appelée la largeur de trait. Nous pouvons également changer la couleur en définissant la propriété de trait. Retirons également le remplissage, qui est automatiquement noir en cas de cercle. Disons simplement remplir : aucun. Si vous voulez être fantaisie, nous pouvons également modifier la propriété stroke-linecap, ce qui rendra nos terminaisons de ligne arrondies. Si vous voulez avoir des couleurs différentes pour les cercles et les croix, alors puisque nous sommes en HTML maintenant, vous pouvez simplement attacher une classe CSS pour la croix ou le cercle, puis définir une couleur différente pour eux en fonction de la classe CSS. Maintenant, nous avons ces beaux cercles et croix. Pour terminer ce jeu, passons à l'une des parties les plus essentielles, qui est l'interaction.
10. Interaction: Ok, regarder bien, mais jusqu'à présent tout est toujours statique et c'est un jeu donc vous voulez ajouter une interaction, donc nous devrions attacher un gestionnaire d'événements pour les carrés. Mais malheureusement, dans React, nous ne pouvons pas attacher de gestionnaires d'événements aux niveaux des composants. Nous devons attacher des gestionnaires d'événements pour les balises HTML réelles. Dans notre cas, le plus proche que nous pouvons obtenir est l'étiquette conteneur à l'intérieur d'un composant Square. Mais il y a un peu de problème ici, nous avons convenu que nous allons avoir l'état dans un composant TicTactoe, mais ce gestionnaire d'événements est maintenant dans le composant Square. Nous devons trouver un bon moyen que le composant Square, peut définir l'état. Une idée pourrait être qu'en plus de transmettre l'état au composant Square, nous pourrions également transmettre la fonction setState, et de cette façon, le composant Square pourrait changer l'état lui-même. Mais en plus de changer l'état de la grille, nous voulons également changer l'état du joueur. Bien sûr, nous pourrions également transmettre au joueur le composant Square
et le composant Square pourrait changer l'état entier car il saura tout. Mais cela va à l'encontre de l'idée d'avoir le composant Square aussi simple que possible, et si vous y pensez, le joueur n'a rien à voir avec le composant Square vraiment. Le joueur appartient à la logique principale qui doit être définie dans le composant TicTactoe. Au lieu de tout transmettre, ce que nous allons faire, c'est de transmettre un rappel. Un rappel est lorsque vous transmettez une fonction, alors vous vous attendez à ce que la fonction soit appelée sur certains événements. Dans notre cas, le composant TicTactoe transmettra une fonction et le composant Square nous appellerons cette fonction une fois qu'il a été cliqué. La bonne chose à ce sujet est que la fonction que nous
transmettons est définie dans le composant TicTactoe, donc il a un accès complet à tout ce qui est à
l'intérieur du composant TicTactoe avec l'état, et le joueur et tandis que un composant Square n'a accès à aucun de ces éléments, il peut toujours appeler la fonction. Dans le composant TicTactoe, nous allons écrire une fonction qui reçoit le carré a été cliqué, et il change l'état en mettant à jour la grille et en changeant le lecteur. Ensuite, passons cette fonction à chacun des carrés, en tant que propriété. Il est important de noter ici que nous n'appelons pas la fonction ici. Nous transmettons juste une référence à la fonction, tout comme nous pourrions le faire avec n'importe quelle autre variable. Le seul endroit où nous allons appeler cette fonction sera à l'intérieur du composant Square, qui va y avoir accès parce que nous le transmettons simplement en tant que propriété. À l'intérieur du composant Square, nous pouvons définir un gestionnaire d'événements pour l'événement click, et ce gestionnaire d'événements nécessite une fonction. Il sera tentant d'utiliser la fonction qui vient d'être transmise à partir du composant TicTactoe, mais ce n'est pas si facile. La fonction transmise par le composant TicTactoe nécessite un attribut position. Ce que nous pouvons faire, c'est que nous pouvons définir un gestionnaire d'événements intermédiaire dans le composant Square, qui est appelé une fois que le carré est cliqué, puis il va transférer pour appeler à notre rappel. Dans ce gestionnaire de clics intermédiaire, nous pouvons facilement transmettre l'
attribut position car le composant Square connaît la position. Nous pouvons également ajouter une logique supplémentaire ici, par exemple, si le carré n'est pas vide, alors nous allons ignorer le clic. Wow, donc on est allés loin, maintenant tu peux vraiment jouer à ce jeu. C' est interactif, ça a l'air sympa. Tout est en place sauf un dernier morceau, annonçant le gagnant.
11. Détection du gagnant: Nous sommes sur le point de terminer ce jeu maintenant, mais nous ne savons toujours pas si le jeu est terminé,
si quelqu'un a gagné le match ou si c'est une égalité. Pour ce faire, écrivons une fonction utilitaire, qui va être une fonction JavaScript simple, puis voyons comment cette fonction JavaScript simple s'intègre dans votre logique d'application. Pour faire ce calcul,
cette fonction aurait besoin de l'état du jeu, il aurait besoin de la valeur de chaque carré. Mais en dehors de
cela, ce serait une fonction JavaScript simple, ce n'est rien de spécifique React, c'est juste une fonction qui reçoit un tableau de neuf valeurs et il donne un résultat. Détecter si quelqu'un a gagné le jeu, c'est vérifier s'il y a trois cercles ou trois croix d'affilée, dans une colonne ou en diagonale. Fondamentalement, nous devons vérifier les éléments spécifiques dans ce tableau de neuf éléments. Si vous voulez vérifier si la première ligne est pleine de cercles, alors nous allons vérifier si le premier, le deuxième et le troisième élément de ce tableau est un cercle. Si je vais à cela la deuxième ligne, la deuxième rangée, alors nous allons vérifier si le quatrième, cinquième et sixième élément de ce tableau est un cercle et ainsi de suite. C' est un chèque super simple. Il est fondamentalement certaines conditions si, si ces valeurs sont tous des cercles, alors la fonction renvoie que le gagnant est cercle. Si ces valeurs sont toutes des croix, alors il retournera que le gagnant est une croix. Si la fonction a vérifié que personne n'a gagné le jeu, alors il y a encore deux options. Le jeu est terminé et c'est une égalité, ou le jeu est toujours en cours. Détecter une cravate à ce stade consiste simplement à vérifier si tous les carrés ont déjà une valeur, donc il n'y a pas de mouvement supplémentaire possible. Dans ce cas, revenons que « C'est une cravate ». La seule option restante est que personne n'a gagné la partie, ce n'est pas une égalité donc le jeu est toujours en cours. Dans ce cas, nous ne retournons tout simplement rien du tout. OK, donc nous avons cette fonction et c'est une fonction utilitaire, donc nous pouvons probablement l'avoir quelque part en dehors des composants React, mais nous pouvons aussi l'avoir dans le composant TicTactoe parce que le composant TicTactoe gère le principal et c'est le seul endroit où cette fonction est nécessaire, donc vous pouvez décider cela. Comment cela s'insète-t-il dans notre application ? Le cycle de vie de ces applications Tic-Tac-Toe jusqu'à présent est que nous rendons le tout comme un état initial, puis une fois que vous cliquez sur l'un des carrés, puis le tout est re-rendu. Cela se poursuit en boucle jusqu'à ce que vous continuiez à cliquer sur les carrés. La détection du gagnant pourrait venir après chaque clic, sorte qu'il pourrait faire partie du gestionnaire d'événements après avoir cliqué sur un carré. Dans ce cas, nous pourrions avoir un état supplémentaire pour le gagnant. Nous pourrions stocker le gagnant dans un état, puis sur la base de cela, nous pourrions rendre un écran de résultat. L' autre option vient en réalisant que le gagnant est un état dérivé. Il est basé sur les états déjà existants, donc nous n'avons pas besoin d'avoir une partie séparée de l'état pour stocker quelque chose que nous pouvons déjà comprendre du reste de l'état. Mais si nous ne le stockons pas dans l'état, alors où l'avons-nous ? Nous devons savoir si quelqu'un a gagné le jeu au rendu, car dans ce cas, nous allons rendre le composant Result. Donc, nous pouvons simplement ajouter une logique supplémentaire entre obtenir l'état du crochet React, qui contient la valeur des carrés et le rendu de la grille basé sur cet état. Tout ce que vous écrivez dans cette fonction, comme nous l'
avons discuté, nous serons réexécutés avec chaque rendu. Lorsque vous rendez ce composant, il détectera si quelqu'un a gagné le jeu et il peut alors prendre une décision de rendre l'écran des résultats en fonction de cela. Donc, ce sont deux options et n'hésitez pas à aller avec celui que vous préférez. En fin de compte, les deux auront une variable gagnante qui
contiendra si le cercle ou la croix a gagné le jeu, ou s'il s'agit d'une égalité ou il ne contiendra rien et cela indiquera que le jeu est toujours activé.
12. Et le gagnant est ..: Dans ce dernier chapitre, nous allons créer notre écran de résultats. Auparavant, nous avons déjà réussi à dériver notre état dans une variable gagnante, qui contiendra, si le jeu a été gagné par le cercle, la croix, ou personne n'a gagné le jeu et le jeu est toujours activé. L' écran des résultats viendra au composant TicTactoe car le composant TicTactoe est celui qui assemble la logique principale du jeu. Dans la mise en page, le résultat apparaîtrait au-dessus de la grille mais techniquement en HTML, il sera à côté parce que la grille a déjà un CSS distinct, qui est spécifique à la grille, et nous ne voulons pas avoir l'écran de résultats à l'intérieur de cela parce que l'écran des résultats aurait l'air quelque chose de complètement différent. Mais maintenant, nous avons deux balises HTML à l'intérieur des résultats des composants TicTactoe. Et dans React, nous ne pouvons pas avoir ça. Réagir doivent toujours retourner une balise HTML en conséquence. Mais nous pouvons facilement corriger cela parce qu' une balise de résultat peut avoir un contenu et que le contenu peut avoir plusieurs balises HTML. C' est exactement la même que notre grille précédente contient neuf carrés. Je vais simplement ajouter une balise wrapper en tant que conteneur pour le composant Tic Tac Toe, qui aurait à la fois la grille et l'écran de résultats. Mais maintenant, l'écran des résultats et la grille apparaissent toujours et nous
voulons seulement avoir l'écran des résultats au cas où quelqu'un aurait gagné la partie ou s'il s'agit d'une égalité. Nous voulons rendre cet écran de résultats conditionnellement basé sur l'attribut gagnant. Nous pouvons faire la même astuce que nous venons de faire dans le composant Square lorsque nous avons rendu un cercle ou une croix en fonction de la valeur du carré. Maintenant, en fonction de la valeur du gagnant, nous allons rendre le résultat. Comme nous l'avons convenu, si le gagnant est vide, cela signifie
que le jeu est toujours en marche. Cela signifierait également que si vous utilisez cette condition, que si le jeu est toujours activé
, l'écran des résultats ne s'affichera pas. Nous avons réussi à masquer l'écran des résultats pendant le jeu. Nous voulons aussi faire en sorte qu'il soit assez intelligent pour savoir qui a gagné le match parce qu'en ce moment il dit simplement le résultat, il ne dit pas quel est le résultat. Pour ce faire, nous devons transmettre l'attribut gagnant à ce composant la même manière que nous avons transmis les attributs aux carrés. Ensuite, de l'autre côté, au composant de résultats, nous devons attraper cette variable et nous pouvons avoir un rendu conditionnel basé sur sa valeur. Par défaut, cela apparaîtrait sous la grille. Mais si vous voulez l'avoir en haut de la grille, alors nous pouvons ajouter un peu de style CSS et avec cela, nous pouvons le définir à position absolue et définir d'autres propriétés pour le rendre un peu plus agréable. Une fois que vous avez terminé le jeu, le gagnant a été annoncé, quelle est la suite ? Si vous voulez jouer un autre tour, alors vous devez actualiser la page. Au lieu de cela, nous pouvons également définir une fonction de réinitialisation qui réinitialiserait notre état. Parce que nous réinitialisons notre état, nous devons le définir dans le composant TicTactoe parce que c'est celui qui a accès à l'état. Mais après cela, nous pouvons transmettre cette fonction de réinitialisation à notre composant d'écran de résultats. Cela va être un autre rappel, tout comme nous passons un rappel au composant Square, qui a été utilisé une fois que vous cliquez sur le carré. Celui-ci sera utilisé si vous cliquez sur le bouton de réinitialisation dans l'écran des résultats. Je vais simplement passer cette fonction en tant que propriété et à l'intérieur du composant de l'écran des résultats, si vous définissez un bouton pour la réinitialisation, alors nous pouvons simplement passer cette fonction au gestionnaire d'événements onClick de ce bouton, sans aucun événement de niveau intermédiaire entre les deux. La différence entre celui-ci et celui
du composant Square est que celui du composant Square
nécessitait une propriété supplémentaire à transmettre à la fonction de composants TicTactoe. Mais celui-ci, les fonctions de réinitialisation n'a pas besoin de propriété du tout, donc il peut être simplement appelé, il peut être simplement lié au gestionnaire d'événements de ce bouton. Et c'est tout ce que c'est. Maintenant, nous avons un jeu que vous pouvez jouer à travers, l'écran de résultat apparaîtra et une fois que vous avez terminé, vous pouvez réinitialiser le jeu et jouer un autre tour.
13. Conclusion: Félicitations. Maintenant, j'ai un jeu Tic-Tac-Toe, et j'espère que vous aurez aussi une bien meilleure compréhension du fonctionnement de React. Mais si vous avez encore quelques questions ou que certaines parties sont encore confuses pour vous, alors n'hésitez pas à me contacter ici ou sur CodePen. Bien sûr, ce jeu est à peine terminé. Nous pourrions avoir beaucoup plus à elle, mais cela aurait fait un tutoriel beaucoup plus long. Au lieu de cela, vous pouvez trouver un lien sous cette vidéo qui
explique d'autres fonctionnalités comme comment ajouter de l'animation à elle, ou comment définir une logique informatique et jouer contre l'ordinateur. N' hésitez pas à poursuivre ce projet, et une fois que vous avez terminé, n'oubliez pas de le partager. J' ai hâte de le voir.