DEV Community

Sebastian Spiegel
Sebastian Spiegel

Posted on

Nav in Native

This week I have been building my first React Native application. I started off with just changing the and styles, making sure I understood how ‘flex’ works and the different core components. To do this I made several component files and took turns returning them as I played with them. But in a real mobile app, which I intended to build, there is navigation, just like in a web app.

So clearly, this wasn’t going to cut it.

return (
    <Welcome />
    // <Index />
  );
Enter fullscreen mode Exit fullscreen mode

Note: If you already have an app and want to incorporate React Native, it’s recommending to use the react-native-navigation library here

There are many libraries to install to use React Navigation. I’m using expo, so I installed using the following, but you can check out the documentation if you have a different setup for your app.

npm install @react-navigation/native
expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm install @react-navigation/stack
Enter fullscreen mode Exit fullscreen mode

If you are familiar with vanilla React (which you really should be first), then the setup for navigation looks very similar to routes, just different words! The setup should happen at the top level of your app (usually App.js). You start off importing these two libraries:

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
Enter fullscreen mode Exit fullscreen mode

Inside of your App function, you then need to have a way to call upon the createStackNavigator function, using this line: const Stack = createStackNavigator();

That’s the setup! Now you have everything you need to use to wrap up the screens that you want to render. So now my App.js is looking like this:

return (
   <NavigationContainer>
     <Stack.Navigator>
       <Stack.Screen name="Welcome" component={Welcome}/>
     </Stack.Navigator>
   </NavigationContainer>

 );
Enter fullscreen mode Exit fullscreen mode

The next time I had to figure out was using props, so I coud also get my Index component working. For the purposes of testing, I had all my data in the top level of my app (later I plan to replace that with a quick fetch to an API I’ve already picked out).

For React Native navigation, you can’t pass an inline function like: component={() => <HomeScreen />}
Instead, much like you would see for a Route in vanilla React, you wrap the component like so:

<Stack.Screen name="Index">
         {props => <Index {...props} cards={cards} />}
</Stack.Screen>
Enter fullscreen mode Exit fullscreen mode

In order for my function to properly receive the props, I used memo (there are a few other options, but this worked well for me!)
So I changed this:

const Index = (props) => {
   return(
      // render here
   )
}
Enter fullscreen mode Exit fullscreen mode

To this:

const Index = React.memo(function Index(props) {
   return(
      // render here
   )
})
Enter fullscreen mode Exit fullscreen mode

My Index is using FlatList, so I was getting a warning on my simulator, which I believe is the Native version of the warning you get when you don’t give child components individual keys in vanilla React. So if you get this error:

Warning: Failed child context type: Invalid child context virtualizedCell.cellKey of type number supplied to CellRenderer, expected string.

Add this where you are rendering the components: keyExtractor={item => item.index_id.toString()}

Now I successfully had two different components, but only the top one will render when the app starts, and unlike a webpage, you don’t have the option of just putting in the URL to get to a different route. So I added a button to my Welcome screen, to navigate to my Index.

<Button color="white"
         onPress={() => {
           navigation.navigate('Index')
         }}
         title="Start"
       />
Enter fullscreen mode Exit fullscreen mode

Note: for functional components, it’s a good idea to destructure props, but if you don’t want to do that remember to put props.navigation.navigate(‘Component’) instead.

If you want to navigate one page back you can use an easy back button like so: <Button title="Go back" onPress={() => navigation.goBack()} />
Though with native-gesture-handler the user can also swipe to move a page back.

So that’s the basics of how I set up navigation in my current React Native application! This is definitely the easiest way to get started, and there is so much more to learn further down the line.

Top comments (0)