La navigation entre écrans
Installation des bibliothèques :
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context
Structure du projet :
Dans le sous-dossier "pages" du projet, placer les fichiers :
qui correspondent chacun à un écran du projet.
Les composants de navigation :
Dans le fichier principal de mon application, App.js, j'importe les bibliothèques fournissant les composants de navigation :
"NavigationContainer" qui gère la liste (et l'état) des nos écrans ;
"createNativeStackNavigator" pour la création de liens vers nos futures pages.
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
J'importe également les composants qui définissent mes écrans. Il s'agit des fonctions "Crud" et "UpdateCrud" décrites respectivement dans les fichiers "./Pages/Crud.js" et " ./Pages/UpdateCrud.js" :
import Crud from './Pages/Crud';
import UpdateCrud from './Pages/UpdateCrud';
Analyse du code :
Par l'appel à la fonction createNativeStackNavigator(), je crée l'objet "stack" qui correspond à l'ensemble de mes écrans (ma pile d'écrans).
const Stack = createNativeStackNavigator();
Cet objet dispose des méthodes Navigator et Screen. Pour le rendu, il faut utiliser le composant global "NavigationContainer" qui doit contenir :
l'état initial de la navigation : Stack.Navigator ;
une déclaration Stack.Screen pour chacun des écrans.
Navigator :
Cette méthode décrit l'état initial par ses propriétés :
initialRouteName : l'écran d'accueil ;
screenOptions : les caractéristiques qui s'appliqueront à tous les écrans.
Screen :
exemple :
<Stack.Screen
name="UpdateCrud"
component={UpdateCrud}
/>
Cette méthode déclare un écran par ses propriétés, (voir la documentation officielle) :
- name (obligatoire) ;
- component (obligatoire) le nom "système" ou de l'objet "fonction-composant" qui crée et affiche l'écran lors de son exécution ;
- options : à utiliser pour transmettre les propriétés navigation et route (associées automatiquement à chaque écran) comme dans l'exemple suivant :
options={({ navigation, route }) => ({
title: 'Update CRUD',
headerLeft: () => (
<Button
onPress={() => navigation.navigate('Crud')}
title="Retour"
color="#f00"
/>
),
})}
La propriété "navigation" dispose de nombreuses méthodes comme :
- navigate :
- passer à un autre écran par navigate(name) où name est la valeur de la propriété name de l'écran à afficher:
- ex : navigate("Crud")
- passer à un autre écran et lui passer des paramètres navigate(name,params) :
- navigation.navigate('UpdateCrud',{
num: arg1,
name: arg2,
course: arg3,
});
- navigation.navigate('UpdateCrud',{
- voir la documentation complète
- passer à un autre écran par navigate(name) où name est la valeur de la propriété name de l'écran à afficher:
De même la propriété "route" dispose de nombreuses méthodes (voir la documentation officielle).
- route :
- key - identifiant unique de l'écran
- exemple "Crud-qsy-xqnCEugjA28i-ZHfN" ;
- params - un objet formé des paramètres définit lors de l'appel de l'écran
- exemple :
pour l'appel navigate('UpdateCrud', { num: 128 , name : 'Lucas' })
param est l'objet { num: 128 , name : 'Lucas' }
- exemple :
- key - identifiant unique de l'écran
Création du composant-écran :
Le code ci-dessous montre la définition du composant-écran "Crud" comme élément réalisant toutes les fonctionnalités de l'écran. Ce composant correspond à la fonction-composant "Crud" qui est ici importée (cf § précédent : les composants de la navigation) et dont le code complet est détaillé ICI.
Sa structure a une des 4 formes suivantes :
exemple 1 :
const Crud =( ) =>{
// définition des constantes, des fonctions ou composant internes
const [ dataBd, setDataBd ]=useState("");
const [ studentName, setStudentName ]=useState("");
const lire =() => {
......
}
......
// la vue rendue
return(
<View style={styles.container}>
{ Lire()}
</View>
)
})
Les paramètres navigation et route ne sont nécessaires que s'ils ont un "rôle" dans la fonctionnalité du composant.
Exemple 2 :
Ce code suivant appelle l'écran "Crud" et lui passe les paramètres {num: 121,name: "Pierre",course: "Informatique", }.
navigation.navigate('Crud',{
num: 121,
name: Pierre,
course: Informatique,
});
Pour accéder à ces paramètres, la fonction-composant-écran "crud" devra être de la forme
const Crud =(route ) =>{
//
const [num, student,course] = route.params;
......
//
return(
<View style={styles.container}>
{ Lire()}
</View>
)
}
Exemple 3 :
L'écran "crud" appelle un autre écran du stack
const Crud =(navigation ) =>{
//
const press = () => {
navigation.navigate('updateDb');
}
......
//
return(
<View style={styles.container}>
{ Lire()}
</View>
)
}
Exemple 4 :
La combinaison est possible :
const Crud =(navigation, route) =>{
......
}
Le code complet :
import React, { useState } from "react";
import { Button } from "react-native";
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Crud from './Pages/Crud';
import UpdateCrud from './Pages/UpdateCrud';
const main = () => {
const Stack = createNativeStackNavigator();
return(
<NavigationContainer>
<Stack.Navigator
initialRouteName="Crud"
screenOptions={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleAlign:'center',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
>
<Stack.Screen
name="Crud"
component={Crud}
options={({ navigation, route }) => ({
title: 'Tester CRUD',
})}
/>
<Stack.Screen
name="UpdateCrud"
component={UpdateCrud}
options={({ navigation, route }) => ({
title: 'Update CRUD',
headerLeft: () => (
<Button
onPress={() => navigation.navigate('Crud')}
title="Retour"
color="#f00"
/>
),
})}
/>
</Stack.Navigator>
</NavigationContainer>
)
}