# Exercices: Navigation ### Exercice 0: Context & AsyncStorage #### 0.1 --- Context Cet exercice à pour but de vous introduire les context en React et sera le seul exercice pour cette notion. Dans cet exercice: - **Créez un context** `Context`. - Créez ensuite un objet qui contient deux fonction: - printBonjour *(qui affiche en console "Bonjour")* - printBonsoir *(qui affiche en console "Bonsoir")* - Dans le `Provider` de votre context passez cette objet en `value` - Créez deux composant qui **utiliserons votre context**: - `ButtonBonsoir`, qui fera appel à `printBonsoir` au clic - `ButtonBonjour`, qui fera appel à `printBonjour` au clic ::: info **createContext()**, **useContext()**, **<Context.Provider>** ::: ::: spoiler Créez un objet avec deux fonction: ``` javascript const valueContext = { printBonjour: () => { console.log(...)}, printBonsoir: () => { console.log(...)} }; ``` ::: --- #### 0.1 --- AsyncStorage ::: warning D'abord installez AsyncStorage: `npm install @react-native-async-storage/async-storage` ::: Vous pouvez retrouver la documentation de `Async Storage`, [ici](https://react-native-async-storage.github.io/async-storage/docs/install/) Cet exercice est là pour vous introduire les local storage en reat-native et sera le seul exercice pour cette notion. Le but de cet exercice est d'écrire un nom et de le sauvegarder dans l'application. Si l'application se ferme et qu'elle se relance, le nom doit toujours être le même. Étapes: - Créez un state `name` et un `TextInput` qui aura pour valeur ce nom et qui le modifiera *(cf: useState)* - Créez un `Button` qui **set** une clé dans le AsyncStorage avec le nom "name" et qui aura pour valeur votre état `name` - Créez un effet au montage du composant qui **get** votre clé "name" dans le AsyncStorage puis qui, une fois la valeur récupérée, change votre état `name` *(cf: useEffect)* ::: info Si vous ne savez pas regardez la doc de **AsyncStorage** donnée plus haut ::: ![](https://i.imgur.com/l4a9zLr.gif) --- ::: danger **Attention !** Les exemples donnés dans ce document sont, comme leur nom l'indique, ici à titre d'exemple. Produisez ce qui vous est demandé dans l'exercice, pas dans l'exemple ::: ### Exercice 1: Navigators, getting started ::: info **DOC de react-navigation**: https://reactnavigation.org/docs/getting-started ::: ::: warning D'abord installez react-navigation: `expo install react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated` `npm install @react-navigation/native-stack` ::: #### 1.1 --- Créez une navigation composée de 3 pages: * Home * Details * About Depuis la page `Home` vous devez pouvoir aller sur la page `Details` et sur la page `About`. Il doit être possible de retourner sur la `Home` depuis ces pages via le bouton "back" situé en haut à gauche. :::spoiler > StackNavigator ::: ###### `Exemple:` ``` Home <-> Details Home <-> About ``` ::: warning **->**: Aller à **<-**: Retour vers **<->**: Aller retour possible ::: --- #### 1.2 --- En reprenant l'exercice précédent, créer la navigation suivante: ``` Home <-> Details Home <-> About Details <-> About ``` * La page `Details` doit afficher votre composant `Hello you` réalisé dans les premiers cours. *(prénom, âge, ville, ...)* * La page `About` doit afficher une description. Celle-ci doit être différente si l'on vient de `Home` ou de `Details`. :::info Passez des paramètres à la route About pour que la description soit différente en fonction de la page d'où nous venons. ::: --- #### 1.3 --- Congifurez la barre de navigation ! * Changez le titre de chacune des pages * Amusez vous avec le style de chacune d'entres elles. * Créer un bouton `+` dans la barre de la page home en haut à droite. Ce bouton doit afficher une Alert pour le moment. #### 1.4 --- Via le bouton `+` créer au préalable, naviguer sur une page Modal. > Une modal est "comme une **popup**", elle ne fait pas partie de votre navigation principale, elle possède généralement un moyen différent d'apparaître ou disparaître. Elle est faite pour se concentrer sur du **contenu ou interaction en particulier**. ::: spoiler https://reactnavigation.org/docs/modal ::: ###### `Exemple:` | IOS | Android | | -------- | -------- | | ![](https://i.imgur.com/qCbfUGB.gif) |![](https://i.imgur.com/HcEKgBw.gif) | <br/> ### Exercice 2: Further navigation ::: warning Installez le système de tabs et de drawer: `npm install @react-navigation/bottom-tabs @react-navigation/drawer ::: #### 2.1 --- Dans cet exercice, créez une navigation avec plusieurs "sections" via une **barre de navigation en bas** :wink:. Chaque section doit posséder un icon différent ``` Section 1 -> Page 1 Section 2 -> Page 2 Section 3 -> Page 3 ``` :::spoiler > TabNavigator ::: #### 2.2 --- Créez une navigation avec deux "sections" via une **un menu déroulant**. Ce menu pourra être ouvert et fermé via un bouton en haut à gauche de la barre de navigation. ``` Section 1 -> Page 1 Section 2 -> Page 2 ``` :::spoiler > DrawerNavigator ::: #### 2.3 --- Nested Navigator Dans cet exercice nous allons combiner deux navigator. En reprenant l'exercice 2.1, créez un TabNavigator ou chaque section devra contenir un lien vers une page `Details`. Cette page `Details` ne doit pas afficher la barre de navigation du bas. ``` Section 1 -> Page 1 <-> Details1 Section 2 -> Page 2 <-> Details2 Section 3 -> Page 3 <-> Details3 ``` ###### `Exemple:` ![](https://i.imgur.com/hFizhAm.gif) #### 2.4 --- Mixer tout les exercices précédent pour obtenir ceci: * L'application doit être constitué d'un menu déroulant avec 2 sections: * `Home` * `Tabs` * La section `Home` doit afficher tout l'exercice 1, y compris la Modal * La section `Tabs` doit contenir: * 3 sections différentes * 1 page `Details` par section (en some l'exercice 2) * Le bouton du menu doit se trouver uniquement sur la page `Home` et la Page `Tabs` ![](https://i.imgur.com/pwWHZkD.gif) <br/> ### Exercice 3: Authentification flow & AsyncStorage Cet exercice consiste à créer un flux d'Authentification. Nous allons réutiliser tout le TP créé jusqu'ici pour ce faire. Le but de cet exercice est: * Avoir une page de **`Login`** avec deux champ et un bouton de connexion. * Lorsque vous êtes **connecté** l'application **redirige** sur votre **navigation** créée jusque là. * Lorsque vous **relancez l'application**, celle ci doit savoir si vous étiez connecté ou non pour vous **rediriger au bon endroit** (soit Login soit Navigation) * Le drawer doit contenir un bouton "**Déconnexion**", qui redirige sur la page `Login` Pour cet exercice vous aurez besoin de `Async Storage`, [ici](https://react-native-async-storage.github.io/async-storage/docs/install/) Celui-ci vous permettra de sauvegarder *"l'état"* de votre connexion (connecté ou non) ::: info ***Context*** Vous devez utiliser les fonctionnalités de react `createContext` et `useContext`. Ces fonctionnalité vous permettront de partager des informations entres vos scènes. Des attributs, des styles, des fonctions, peu importe... mais des fonctions me semble une bonne idée pour cet exercice. :wink: ::: #### [Ce lien](https://reactnavigation.org/docs/drawer-navigator/#props) pourrait vous être util et [celui-ci](https://reactnavigation.org/docs/auth-flow/) peut être ::: spoiler #### Quelques étapes à suivre, ou pas, pour réussir: > Créez un "SplashScreen" vous permettant de récuperer les données du storage pour savoir ou rediriger l'utilsateur par la suite > **Etape 1:** Créer un état `isLoading` qui permettra soit d'afficher le Splashscreen soit le reste de la navigation > > **Etape 2:** Créer un état `isSignIn` qui permettra soit d'afficher le Home (votre navigation créée jusqu'ici dans les exercices précédents) soit la page Login > > **Etape 3:** Créer un context qui contiendra les fonctions `login` et `logout` dans lesquels vous utiliserez `AsyncStorage` > > **Etape :4** Créer un effet au montage de votre Router pour récupérer les données de votre AsyncStorage et ainsi altérer les valeurs de `isLoading` et/ou `isSignedIn` ::: ###### `Exemple:` ![](https://i.imgur.com/EUkE4sv.gif)