Search code examples
react-nativereact-native-navigation

How To Call Our Own Build withNavigation In React Native 6


Help,

Firstly, did React Native 6 or 5 have withNavigation ? I cannot find it in the documentation in React Native website.

So, I found some thread that we can build our own withNavigation like this :

withNavigation.js

import React from 'react';
import { useNavigation } from '@react-navigation/native'; // not sure package name


export const withNavigation = (Component) => {
  return (props) => {
    const navigation = useNavigation();

    return <Component navigation={navigation} {...props} />;
  };
};

But I don't know how to call or use the own build withNavigation.

This is my source code :

ResultList.js

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import ResultsDetail from './ResultsDetail';
import { withNavigation } from '../helper/withNavigation';

const ResultList = ({ title, results }) => {
    console.log(withNavigation.component);
    return (
        <View style={styles.container}> 
            <Text style={styles.title}>{title}</Text>            
            <FlatList
                horizontal={true}
                showsHorizontalScrollIndicator={false}
                data={results}
                keyExtractor={(results) => results.id}
                renderItem={({item}) => {
                    return (
                        <TouchableOpacity onPress={() => withNavigation('ResultShowScreen')}>
                            <ResultsDetail results={item} />
                        </TouchableOpacity>
                    )
                }}

            />
        </View>
    )
};

const styles = StyleSheet.create({    
    title: {
        fontSize: 18,
        fontWeight: 'bold',
        marginLeft: 15,
        marginBottom: 5,

    },
    container: {
        marginBottom: 10
    }
});

export default ResultList;

In here :

console.log(withNavigation.component)

it show : undefined

How to get the navigation props with our own withNavigation ?

Thank You


Solution

  • Since your helper function, withNavigation, is a Higher-Order Component (HoC) you have to wrap your component with it in order to be able to use it:

    const ResultList = ({ title, results, navigation }) => {
      return (
        <View style={styles.container}>
          <Text style={styles.title}>{title}</Text>
          <FlatList
            horizontal={true}
            showsHorizontalScrollIndicator={false}
            data={results}
            keyExtractor={(results) => results.id}
            renderItem={({ item }) => {
              return (
                // Now you can use the navigation prop inside of your component
                <TouchableOpacity onPress={() => navigation.navigate('MyRoute')}>
                  <ResultsDetail results={item} />
                </TouchableOpacity>
              );
            }}
          />
        </View>
      );
    };
    
    // withNavigation adds the navigation property to your ResultList component's properties
    export default withNavigation(ResultList);
    

    I think the reason why you can't find withNavigation inside of React Navigation 5 or 6 anymore is because they suggest you to use their built-in hooks instead. I am not sure why do you need to use a custom made HoC when you could just use the useNavigation hook. If you don't have a specific reason to use your custom HoC, the built-in hooks could simplify your code:

    import { useNavigation } from '@react-navigation/native';
    
    const ResultList = ({ title, results }) => {
      const navigation = useNavigation();
    
      return (
        <View style={styles.container}>
          <Text style={styles.title}>{title}</Text>
          <FlatList
            horizontal={true}
            showsHorizontalScrollIndicator={false}
            data={results}
            keyExtractor={(results) => results.id}
            renderItem={({ item }) => {
              return (
                // You can use the navigation property inside of your component
                <TouchableOpacity onPress={() => navigation.navigate('MyRoute')}>
                  <ResultsDetail results={item} />
                </TouchableOpacity>
              );
            }}
          />
        </View>
      );
    };
    
    export default ResultList;