Aller au contenu principal

Plusieurs écrans avec Expo Router

Créer un vrai écran d'accueil, déplacer le jeu dans son propre écran et naviguer de l'un à l'autre.

Objectifs de la séance​

  • comprendre le routage par fichiers : un fichier de src/app/ = un écran = une adresse ;
  • régler le titre de chaque écran avec Stack.Screen dans _layout.tsx ;
  • naviguer vers un autre écran avec router.push ;
  • comprendre la pile d'écrans et le bouton « retour » ;
  • savoir pourquoi les routes typées demandent de relancer npx expo start.

Petite vérification​

Avant de commencer, vérifiez si vous savez...

  1. lancer l'application dans le navigateur, répondre à une question et lire le texte du badge en haut à droite de l'écran
  2. exécuter npm test et lire le nombre de tests réussis
  3. exécuter git branch dans le terminal et dire quelle branche est active (repérée par une étoile)
📌 Réponse attendue

TP pour réfléchir et résoudre des problèmes​

Votre application n'a qu'un écran : le jeu démarre dès l'ouverture. Votre mission : créer un écran d'accueil avec un bouton « Jouer », et déplacer le jeu dans un écran partie. Gardez npx expo start lancé.

Étape 1 — Créer la branche du tutoriel​


Bonne pratique - Repartir de main à jour

git pull avant de créer la branche garantit que vous partez de la dernière version de main : vous évitez les conflits au moment de la fusion.

Étape 2 — Déplacer le jeu dans l'écran partie​

Créez le fichier src/app/partie.tsx : copiez-y tout le contenu de src/app/index.tsx, puis renommez la fonction Accueil en Partie. C'est maintenant la route /partie.


Bonne pratique - Le nom du fichier est l'adresse de l'écran

partie.tsx devient l'adresse /partie. Le nom de la fonction (Partie) n'a pas d'importance pour le routage, mais le garder cohérent avec le fichier rend le code plus lisible.

Étape 3 — Écrire le nouvel écran d'accueil​

Remplacez maintenant tout le contenu de src/app/index.tsx par un écran très simple : un titre, une phrase de présentation et un bouton. Un clic sur le bouton empile l'écran partie au-dessus de l'accueil.

Sans oublier l'importation import { router } from "expo-router"; en tête de fichier.


Bonne pratique - Un écran d'accueil léger

L'accueil ne contient aucune logique de jeu : il présente l'application et oriente. Chaque écran a un seul rôle.

Étape 4 — Donner un titre à chaque écran​

Dans src/app/_layout.tsx, déclarez les deux écrans avec Stack.Screen, pour régler le titre de la barre du haut.


Bonne pratique - Des titres qui orientent

Le titre d'un écran répond à la question « où suis-je ? ». « Partie en cours » est plus parlant que « partie », le nom de fichier affiché par défaut.

Étape 5 — Relancer pour régénérer les routes typées​

Votre projet utilise des routes typées : TypeScript connaît la liste des adresses valides. Cette liste est stockée dans un fichier généré (.expo/types/router.d.ts) que la commande npx expo start met à jour. Tant que vous ne l'avez pas relancée après la création de partie.tsx, VS Code peut souligner router.push("/partie") en rouge.

Dans le navigateur, cliquez sur « Jouer » : l'adresse devient /partie, le jeu démarre, et un bouton retour apparaît dans la barre du haut.


Bonne pratique - Relancer après avoir créé un fichier d'écran

Si l'éditeur signale une route inexistante alors que le fichier existe, relancez npx expo start avant de chercher une erreur dans votre code : les types sont simplement périmés.

Étape 6 — Enregistrer votre travail​

La branche feature/navigation n'existe pas encore sur GitHub : la première fois, il faut donc ajouter -u.


Bonne pratique - Vérifier la branche avant de commiter

git status commence par « On branch feature/navigation » : prenez l'habitude de le lire. Un commit sur la mauvaise branche est facile à faire et pénible à défaire.

📌 Une solution

Notions théoriques​

Le routage par fichiers​

Avec Expo Router, il n'y a pas de liste d'écrans à déclarer dans le code : c'est l'arborescence des fichiers de src/app/ qui définit les écrans et leurs adresses (appelées routes).

FichierRoute (adresse)Écran
src/app/index.tsx/accueil
src/app/partie.tsx/partiele jeu
src/app/_layout.tsx(aucune)mise en page commune à tous les écrans

Sur le Web, la route est visible dans la barre d'adresse du navigateur (http://localhost:8081/partie) ; sur mobile, elle sert de nom interne à l'écran. C'est le même code pour les deux.

La pile d'écrans (Stack)​

Le fichier _layout.tsx renvoie un composant <Stack> : les écrans sont empilés les uns sur les autres.

Avant « Jouer » Après « Jouer »
+-----------+ +-----------+
| accueil | | partie | <- écran visible (haut de la pile)
+-----------+ +-----------+
| accueil |
+-----------+
  • router.push("/partie") ajoute l'écran partie au-dessus de la pile ;
  • le bouton retour (ou le geste de retour sur mobile) retire l'écran du haut et ramène à l'accueil.

Stack.Screen : régler un écran​

<Stack>
<Stack.Screen name="index" options={{ title: "Quiz Cyber" }} />
<Stack.Screen name="partie" options={{ title: "Partie en cours" }} />
</Stack>
  • name : le nom du fichier sans extension (index ou partie) ;
  • options : un objet de réglages (ici le title, affiché dans la barre du haut).

À la séance « Anatomie d'un projet », vous aviez utilisé screenOptions pour régler tous les écrans en une fois. Stack.Screen règle un seul écran.

router.push​

router.push("/partie") navigue vers une route. Avec les routes typées (option typedRoutes du projet), TypeScript vérifie que l'adresse existe : router.push("/parti") est signalé comme une erreur avant même d'exécuter l'application.

Les types viennent d'un fichier généré

Le fichier .expo/types/router.d.ts est généré par npx expo start à partir des fichiers de src/app/. Il n'est pas versionné (il est dans le .gitignore) : chaque développeur le regénère sur son poste.

Recharger la page sur le Web

Sur le Web, une route est une vraie adresse : si vous rechargez la page /partie, le navigateur ouvre directement cet écran, sans passer par l'accueil, et une nouvelle partie démarre. Et n'importe qui peut taper une adresse à la main. Dès la prochaine séance, vous apprendrez à ne jamais faire confiance à ce qui vient d'une adresse.


Test de mémorisation/compréhension​


Quel fichier définit l'écran accessible à l'adresse /partie ?


Quel est le rôle du fichier _layout.tsx ?


Que fait router.push("/partie") ?


À quoi correspond l'attribut name="partie" de Stack.Screen ?


Pourquoi relancer npx expo start après avoir créé un nouvel écran ?


Que se passe-t-il quand on appuie sur le bouton retour depuis l'écran partie ?



Exercices complémentaires​

Exercice A : un titre plus engageant​

Changez le titre de l'écran d'accueil dans _layout.tsx (par exemple « Bienvenue au Quiz Cyber ») et vérifiez le résultat dans l'onglet du navigateur et dans la barre du haut.

Exercice B : tester une adresse tapée à la main​

Dans le navigateur, tapez directement l'adresse http://localhost:8081/partie (le numéro de port est celui affiché par npx expo start). Que remarquez-vous (accueil visité ? bouton retour ? score) ? Que se passerait-il sur un site dont l'adresse contiendrait des réglages comme /partie?nombre=999 ? Gardez la question en tête pour la séance suivante.


Ce qu'il faut retenir​

NotionRésumé
Routage par fichiersUn fichier de src/app/ = un écran = une route (partie.tsx donne /partie).
_layout.tsxMise en page commune : ici un Stack (pile d'écrans).
Stack.ScreenRègle un écran : name = nom du fichier, options = titre et réglages.
router.pushEmpile un écran ; le bouton retour le retire.
Routes typéesTypeScript vérifie les adresses ; npx expo start régénère les types.
Une branche par tutorielfeature/navigation : commits sur la branche, fusion par Pull Request en fin de tutoriel.

Aperçu de la prochaine séance​

Le bouton « Jouer » lance toujours une partie de 5 questions quelconques. Dans la prochaine séance, vous allez créer l'écran générateur de quiz : le joueur choisit un thème, un niveau et un nombre de questions, puis ces réglages sont transmis à l'écran de partie.