Créer des applications mobiles avec React Native

Auteur: Mohamed CHINY Durée necessaire pour le cours de Créer des applications mobiles avec React Native Niveau recommandé pour le cours de Créer des applications mobiles avec React Native Supports vidéo non disponibles pour ce cours Exercices de renforcement non disponibles pour ce cours Quiz non disponibles pour ce cours

Page 16: Naviguer entre les vues d'une application mobile

Toutes les pages

Naviguer entre les vues d'une application mobile

Bibliothèque React Natigation

React Navigation est la bibliothèque de référence pour gérer la navigation entre les vues (ou écrans) dans une application mobile réalisée avec React Native. En effet, dans une application mobile (et comme c'est le cas pour les applications Web), le contenu est éparpillé sur plusieurs vues. Par exemple, la vue d'accueil donne un aperçu général sur l'application et donne accès aux différentes autres vues plus spécialisées, comme la vue des produits, la vue d'inscription, la vue d'authentification... La bibliothèque React Navigate permet de structurer l’expérience utilisateur en définissant des parcours clairs, que ce soit via des piles d’écrans (stack), des onglets (tab), ou des tiroirs latéraux (drawer).

Grâce à son intégration fluide avec Expo et sa modularité, elle offre une grande flexibilité pour créer des transitions intuitives, passer des paramètres entre vues et gérer les comportements complexes comme le deep linking ou les animations. C’est un outil essentiel pour toute application mobile bien structurée.
Dans cette section, nous allons voir la navigation en pile d'écran (ou stack). Les autres techniques comme tab ou drawer seront traitées plus tard, mais le concept général reste similaire.

Installation des modules nécessaire pour la navigation

React Navigate repose sur de nombreuses bibliothèques qui permettent le bon fonctionnent du processus de navigation entre les vues. Avant d'implémenter la navigation dans le code, il faut d'abord installer ces bibliothèques à travers la ligne de commande (terminal) comme ceci:
npm install @react-navigation/native
npx expo install react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated
npm install @react-navigation/native-stack
Vous pouvez lancer ces installations en une seule fois au lieu de les exécuter l'une après l'autre.
Expliquons rapidement le rôle de chacune de ces bibliothèques:

@react-navigation/native
C’est la bibliothèque principale qui gère la logique de navigation dans une application React Native. Elle fournit le NavigationContainer qui est indispensable pour encapsuler l’ensemble de la navigation et permet de définir les routes et les transitions entre les écrans.

@react-navigation/native-stack
Ce module ajoute la navigation en pile (ou stack) où chaque écran est empilé comme des cartes. Il permet de naviguer en avant (navigate) ou en arrière (goBack) entre les vues avec des transitions fluides et une gestion optimisée de l’historique de navigation.

react-native-screens
Cette bibliothèque améliore les performances en optimisant le rendu des écrans natifs. Elle permet de monter et démonter les vues de manière plus efficace en réduisant la consommation mémoire et en accélérant les transitions.

react-native-safe-area-context
Elle garantit que le contenu de l’application respecte les zones sûres des appareils (encoches, bords arrondis, barres de statut). Elle évite que des éléments importants soient masqués ou mal positionnés en fournissant des marges dynamiques adaptées à chaque appareil.

react-native-gesture-handler
Cette bibliothèque gère les gestes complexes comme les swipes, les pressions longues, les glissements, etc. Elle est essentielle pour les interactions fluides et naturelles, notamment dans les transitions entre écrans ou les composants interactifs comme les carrousels.

react-native-reanimated
Elle permet de créer des animations performantes et fluides en utilisant un moteur natif. Contrairement aux animations JavaScript classiques, celles-ci sont calculées côté natif, ce qui a pour effet d'améliorer la réactivité et la fluidité.

Exemple de navigation entre deux vues

Supposons que l'on souhaite créer deux vues nommées respectivement "Home" et "Contact". Par défaut, la vue "Home" sera activée. Dans chaque vue, on intègrera un bouton qui permet de naviguer vers l'autre vue.
Par souci de simplicité, nous allons seulement intégrer (en plus du bouton) un composant texte qui accueille les messages "Home" et "Contact" afin d'identifier la page sur laquelle on se situe à tout moment.
Avant de mettre en place la navigation, nous allons créer nos deux vues de la même façon qu'on a créé les composants réutilisables. Je vous renvoie vers la leçon de la réutilisation des composants en React Native si vous avez besoin de plus d'informations.

Dans notre dossier "components" (qu'on avait créé à la racine du projet), nous allons ajouter les deux fichiers "Home.js" et "Contact.js" qui contiennent les codes suivants:

Home.js
import {Text, StyleSheet, View, Button} from 'react-native'
export default function Home({navigation}){
   return(
      <View style={styles.container}>
         <Text style={{textAlign:"center"}}>
            Home
         </Text>
         <Button
            title="Aller à Contact"
            onPress={
               ()=>navigation.navigate("Contact")
            }
          />
      </View>
   )
}
const styles=StyleSheet.create({
   container:{
      flex:1,
      justifyContent:"center",
      alignItems:"Center",
      backgroundColor:"#CCC"
   }
})
Contact.js
import {Text, StyleSheet, View, Button} from 'react-native'
export default function Contact({navigation}){
   return(
      <View style={styles.container}>
         <Text style={{textAlign:"center"}}>
            Contact
         </Text>
         <Button
            title="Aller à Home"
            onPress={
               ()=>navigation.navigate("Home")
            }
          />
      </View>
   )
}
const styles=StyleSheet.create({
   container:{
      flex:1,
      justifyContent:"center",
      alignItems:"Center",
      backgroundColor:"#CCC"
   }
})
Nous allons voir l'explication de ces code en détail juste après.

Quant au code du composant principal App.js qui orchestre toute l'opération, il ressemblera à ceci:
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Home from './components/Home';
import Contact from './components/Contact';

const Stack = createNativeStackNavigator();

export default function App() {
   return (
      <NavigationContainer>
         <Stack.Navigator initialRouteName="Home">

            <Stack.Screen name="Home"
            component={Home} />

            <Stack.Screen name="Contact"
            component={Contact} />

         </Stack.Navigator>
      </NavigationContainer>
   );
}

Explication des codes

Commençons par le code du composant principal App.js:

La première opération consiste à importer les modules NavigationContainer qui inclut le composant racine qui encapsule tout le système de navigation (<NavigationContainer>) et createNativeStackNavigator qui crée un navigateur en pile (stack navigator). La navigation en pile utilise des transitions natives optimisées, plus fluides et performantes que les navigateurs JS classiques.

N'oublions pas d'importer aussi les deux composant réutilisables Home et Contact.
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Home from './components/Home';
import Contact from './components/Contact';
Ensuite, on crée une instance du navigateur en pile (stack navigator) dans React Native:
const Stack = createNativeStackNavigator();
Cette instruction a pour effet de générer un objet qui contient deux composants : Stack.Navigator qui représente le conteneur qui définit la structure de navigation et Stack.Screen qui définit les écrans que l'on veut inclure dans cette pile. Ces deux composants seront invoqués juste après.

Le composat principal App.js retourne le code qui implémente le système de navigation principal de l'application:
<NavigationContainer>
   <Stack.Navigator initialRouteName="Home">

      <Stack.Screen name="Home"
      component={Home} />

      <Stack.Screen name="Contact"
      component={Contact} />

   </Stack.Navigator>
</NavigationContainer>
Le composant racine NavigationContainer fourni par le module @react-navigation/native initialise le contexte de navigation et doit entourer tous les navigateurs (Stack dans notre cas).

Le composant <Stack.Navigator initialRouteName="Home"> indique que l’écran Home sera affiché en premier au lancement de l’application.

Dans ce bloc:
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Contact" component={Contact} />

chaque ligne déclare un écran dans la pile. L'attribut name est l’identifiant utilisé pour naviguer et component est le composant React à afficher pour cet écran.

Quant aux codes de Home.js et Contact.js, ils sont presque similaires à l'exception du message à afficher et la cible du bouton.

Prenons le code de Home.js:
export default function Home({navigation}){
   return(
      <View style={styles.container}>
         <Text style={{textAlign:"center"}}>
            Home
         </Text>
         <Button
            title="Contact"
            onPress={
               ()=>navigation.navigate("Contact")
            }
         />
      </View>
   )
}
La prop navigation est passée par défaut au composant Home car ce dernier est déclaré comme écran dans Stack.Navigator de App.js. Cette prop qui implémente l'objet Navigation dispose de la méthode navigate (navigation.navigate("Contact")) qui est utilisée pour changer d’écran dans une application React Native utilisant React Navigation. En effet, l'instruction de navigation qui est exécutée dans l'event handler du bouton ordonne au système de navigation de charger la vue implémentée par le composant Contact dans ce cas.