Velidan
Velidan

Reputation: 6019

How to use React Navigation Drawer with Next.js?

I'd like to use the React Navigation v5 (Drawer navigation) with Next.js but I have a question about their integration.

In short: React Navigation (Drawer navigation) based on the React Navigation Screens component. It conditionally renders the correct Screen.

The problem is: Next.js has it's own routing system based on the Folder structure. eg. each file in /pages folder automatically generates an appropriate route so I can't add these files as a React Navigation Screen (at least I'm not sure it's possible at all)

How to make these tools to work together and save the Next.js SSR feature?

Example of the React Navigation Drawer:

import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button
        onPress={() => navigation.navigate('Notifications')}
        title="Go to notifications"
      />
    </View>
  );
}

function NotificationsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button onPress={() => navigation.goBack()} title="Go back home" />
    </View>
  );
}

const Drawer = createDrawerNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator initialRouteName="Home">
        <Drawer.Screen name="Home" component={HomeScreen} />
        <Drawer.Screen name="Notifications" component={NotificationsScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

Thanks for any help!

Upvotes: 4

Views: 5989

Answers (1)

wispamulet
wispamulet

Reputation: 76

You should use file based routing system from Nextjs on web and do your own navigation on mobile using React Navigation.

Below is my approach,

// this is how your directory might look like

- pages/
  - index.tsx // this is your entry point for web
  - about.tsx
App.tsx // this is your entry point for native
// pages/index.tsx
import React from 'react';
import { Text, View } from 'react-native';

const Home: React.FC = () => (
  <View>
    <Text>Welcome to Expo + Next.js 👋</Text>
  </View>
);

export default Home;

// pages/about.tsx
import React from 'react';
import { Text, View } from 'react-native';

const About: React.FC = () => (
  <View>
    <Text>This is about page!</Text>
  </View>
);

export default About;

Define your navigator for native app in App.tsx, it will only work on mobile so it doesn't have to be the same as what you have in pages/ folder. (actually if you only want your app run in browser, you don't need it at all.

Nextjs will handle all the route things, SSR etc... just like a normal Nextjs app when you run it in a browser.

// App.tsx
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import Home from '../pages/index';
import About from '../pages/about';

const Drawer = createDrawerNavigator();

const App: React.FC = () => (
  <NavigationContainer>
    <Drawer.Navigator>
      <Drawer.Screen name="Home" component={Home} />
      <Drawer.Screen name="About" component={About} />
    </Drawer.Navigator>
  </NavigationContainer>
);

export default App;

The important thing is how should you change routes when you have your navigation on native app but an automatically routing system on web?

There is a package to solve this expo-next-react-navigation, check the documentation for details! Make sure you're using the correct version of this package, if you're using React Navigation 5, you should install [email protected] at this moment.

And here is an example, it should work on both platforms,

import React from 'react';
import { FlatList, Text } from 'react-native';
import { Link } from 'expo-next-react-navigation';

const links = [
  { key: 'home', route: '' },
  { key: 'about', route: 'about' },
];

const Links: React.FC = () => (
  <FlatList
    data={links}
    renderItem={({ item }) => (
      <Link routeName={item.route}>
        {item.key}
      </Link>
    )}
  />
);

export default Links;

Upvotes: 6

Related Questions