Add a Modal with Typed Navigation to a React Native App with React Navigation v6

Kadi Kraman
InstructorKadi Kraman
Share this video with your friends

Social Share Links

Send Tweet

We'll use the Stack Navigator from React Navigation v6 to display a modal for the story details page.

Then add TypeScript types for the navigation state to ensure correct typing.

Resources:

  • React Navigation: https://reactnavigation.org/
  • Stack Navigator: https://reactnavigation.org/docs/stack-navigator/

Checkpoint: Add a story details modal

Instructor: [0:00] Now that we have a tab for our bookmarks and these stories list, we want to be able to open a full-screen modal for the story details.

[0:08] Heading over to React Navigation, version 6 documentation, and to Hello React Navigation, let's copy the install command from the stack navigator, and paste it into your terminal. Because this includes Native dependencies, we'll need to cd into the iOS directory from portal store.

[0:24] Go back to the root of the project and rebuild the app. In your screens directory, create a new file. We'll call it root.navigator.tsx. In here, we'll import Star as React from React, and Create Native Stack Navigator from React Navigation.

[0:41] We'll declare a constant for the root stack with Create Native Stack Navigator. We'll export const root navigator. This will be a React component, and return an error function. From here, we'll return the root stack.navigator. In the navigator, we will have a screen. We'll call this screen, bottom tabs.

[1:04] For the component, we'll pass in the bottom tab navigator. Heading over to app.tsx, we want to import the root navigator and return this instead of the bottom tab navigator. We'll now notice that we actually get two headers.

[1:19] To get rid of that, going back to the root navigator and to the bottom tabs screen, let's also pass in an options object. In the options object, we'll do header shown false, which will hide the additional header.

[1:33] The reason we've had to do this is so we could place the modal component adjacent to the bottom tabs. In the screens directory, add a new file called story details modal.screen.tsx. Let's copy the contents of the bookmark screen and paste it into story details.

[1:51] We'll rename bookmark screen to Story Details Modal, and replace the text with story details. In the root navigator, we'll want to add another screen, so rootstack.screen. Let's name it the story details modal, and the component will be the story details modal.

[2:10] Heading over to the home screen, let's import the useNavigation hook from React Navigation. In our home screen component, let's do const navigation = useNavigation. Import pressable from React Native, and scroll down to the flat list where we have our render item.

[2:29] Let's replace the view with the pressable and on press, so whenever the user taps on any of the story items. Let's pass in an Arrow function. We'll do navigation.navigate. We'll pass in the name of the screen, in our case, the Story Details Modal.

[2:46] When I tap on any of the stories, I get taken to the Story Details Modal. You will have noticed that I have a red underline here. This is because I'm using Typescript, but I haven't actually typed any of the navigation.

[2:58] Head over to the source directory and create a new file called types.ts. In this file, let's export type, bottom tab param list. This param list will need to mirror what our bottom tabs navigator actually returns. We have two screens here, the home screen and the bookmark screen.

[3:16] Neither of these screens need any arguments in order to navigate to them. In our types, we will do home undefined, and bookmarks undefined. This object is a key value pair, where the key is the name of this screen.

[3:30] The value will be the object containing the parameters needed to navigate to that screen. On the root navigator, we have two screens. One is for the bottom tab and the other for the modal. In types, let's export type rootstack param list.

[3:45] For the bottom tabs, we'll need to import the navigator screen params from React Navigation. We'll do bottom tabs, navigation screen params, and we'll pass in the bottom tabs param list. For the Story Details Modal, let's pass in undefined for now.

[4:00] Heading over to the bottom tab navigator, we'll import the bottom tab param list from our types. Here where we create the bottom tab navigator, we can pass in the types.

[4:11] These types will now inform us if we made any mistakes with the screens or if we've forgotten to add a new screen to the param list. I'm getting a red underline here saying that bookmarks doesn't exist in the bottom tab param list. Sure enough, I've made a typo.

[4:25] If we rename this to bookmarks and Save, and head over to the bottom tab navigator, the Typescript error is gone. We want to open the root navigator and import the rootstack param list from types and pass it into our Create Native Stack Navigator.

[4:40] Finally, in our home screen, let's import the rootstack param list from our types. Let's also import the native stack navigation prop from the Native Stack Navigation. Where we initialized our useNavigation hook, let's pass in the Native Stack Navigation prop.

[5:00] This in turn will need the rootstack param list. When we scroll down, we can see that our navigation.navigate call is happy with the Story Details Modal. Whereas if we passed in a screen that doesn't exist, it will tell us that this screen doesn't exist in our types.

[5:15] Another problem we have is that our modal doesn't look very much like a modal because it animates in from the side. We can change this animation with the modal screen options. In our root navigator, in the story details modal, let's pass in options and presentation modal. When we tap on any of the stories, it will open a modal with the default platform-specific modal animation.