React Navigation V5 (librairie de React Native)

Cette librairie est considérée comme importante car elle est incluse par défaut quand vous bootstrapez un projet React Native.

Contenu

React Navigation V5

Bare react Native CLI

⚠️ StackNavigator V4 is deprecated, use createStackNavigator instead in V5

#Step 1:
$ npm install @react-navigation/native @react-navigation/stack
#Step 2: install the required peer dependencies
$ npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

Configuration initiale de React Navigator

Il vous faut installer le package principal et tous les package suivants

$ npm install @react-navigation/native
$ npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

Configuration native pour Android

Pour Android, pas d’installation, mais ajouter deux lignes dans le fichier build.gradle dans votre_projet/android/app/build.gradle dans la directive dependencies

 dependencies {
    ....
  implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
  implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
}

Installation des fichiers natifs IOS

$ cd ios; pod install; cd ..

Chargement de gesture handler en tout début de script du fichier d’entrée App.js ou index.js, cet import doit être vraiment le tout premier code Js de votre projet.

# dans index.js (ou App.js si pas de index.js)
import 'react-native-gesture-handler';

Pour IOS React navigation a besoin de cette opération: Cocoapod

Note: For iOS with bare React Native project, make sure you have Cocoapods installed

IOS. install cocoapod : mandatory for React Native 0.60+ (https://medium.com/@appstud/add-a-splash-screen-to-a-react-native-app-810492e773f9)

$ sudo gem install cocoapods

***Passing data to Screen:

<Button
        title="Go to Details"
        onPress={() => {
          /* 1. Navigate to the Details route with params */
          navigation.navigate('Details', {
            itemId: 86,
            otherParam: 'anything you want here',
          });
        }}
      />

passing initial param to a screen from <Stack.Screen>
<Stack.Screen
  name="Details"
  component={DetailsScreen}
  initialParams={{ itemId: 42 }}
/>


Retrieving from the destination Screen :
function DetailsScreen({ route, navigation }) {
  /* 2. Get the param */
  const { itemId } = route.params;
  const { otherParam } = route.params;
    ....

Pour migrer de la version 4 de React Navigation à la 5, voici le lien, principale différence dans la version 5

« In React Navigation 5.x, we have split the navigation prop into 2 props: navigation prop contains helper methods such as navigate, goBack etc., route prop contains the current screen’s data (previously accessed via navigation.state).

In React Navigation 5.x there’s no createAppContainer which provided screens with navigation context. You’ll need to wrap your app with NavigationContainer provider.

Imbrication de routes

On a des creens qui sont contenu dans des navigators, si on a un lien d’un autre navigator, si depuis l’écran SignupScreen, on a un lien vers HistoryScreen, il y aura une erreur, car le screen History n’est pas connu du HomeStack navigator.

<HomeStack.Navigator>
    <HomeStack.Screen name="SignUp" component={SignUpScreen} />
</HomeStack.Navigator>

<ProfileStack.Navigator>
        <ProfileStack.Screen name="Profil" component={ProfileScreen} />
        <ProfileStack.Screen name="History" component={HistoryScreen} />
        <ProfileStack.Screen name="Edit" component={EditScreen} />
</ProfileStack.Navigator>

Pour permettre la navigation inter navigator, il faut déclarer dans le Homestack navigator le screen History

<HomeStack.Navigator>
    <HomeStack.Screen name="SignUp" component={SignUpScreen} />
    <HomeStack.Screen name="History" component={HistoryScreen} />
</HomeStack.Navigator>

<ProfileStack.Navigator>
        <ProfileStack.Screen name="Profil" component={ProfileScreen} />
        <ProfileStack.Screen name="History" component={HistoryScreen} />
        <ProfileStack.Screen name="Edit" component={EditScreen} />
</ProfileStack.Navigator>

Nesting Navigation: https://reactnavigation.org/docs/nesting-navigators/

function Home() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Feed" component={Feed} />
      <Tab.Screen name="Messages" component={Messages} />
    </Tab.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={Home} />
        <Stack.Screen name="Profile" component={Profile} />
        <Stack.Screen name="Settings" component={Settings} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

PRO TIP : Régler le problème du refresh lors d’un goBack()

React navigation possède un défaut : imaginez que vous soyez dans votre page profile dans une application, vous voulez éditer, et quand l’édition est finie vous revenez visualiser votre page de profile, les informations ne se rafraichissent pas, car le goBack() ne gère pas le rafraichissement.

Voici une méthode pour forcer le rafraichissement de la page profile (qui est la page parente, la page édition de profile étant la page enfant).

Quand vous passez de la page Profile à EditionProfile, vous allez passer une fonction en props, que vous allez exécuter dans la page enfant EditionProfile, juste avant de revenir à la page parente Profile. Cette fonction va muter une variable arbitraire qui existe dans la page parente, comme ça on pourra détecter la mutation de cette variable au sein de notre hook useEffect.

const [foo, setFoo] = useState(1) 

   useEffect(() => {

        fetch(getUserInfoUrl, {
            method: 'GET',
            headers: headers,
        })
            .then(response => {
                return response.json()
            })
            .then(data => {
                console.log(data)
                setUser(data)
            })
        //AJAX LOAD
        setShowLoader(false)

    }, [foo]) /// foo est la variable surveillée par useEffect pour se déclencher, si vous ne savez pas ce qu'est un hook useEffect allez voir la documentation.

La fonction définie dans Profile et passée puis exécutée dans la page EditionProfile (pas dans Profile, oui on peut passer des props fonction dans React)

    const handleOnNavigateBack = () => {
        setFoo(foo + 1)
    }

Dans la page ProfileEdit

...
          onNavigateBack() // exécuter cette fonction va incrémenter foo dans la page parente !
          navigation.navigate('Profil')
...
Retour en haut