react-nativereact-navigationreact-navigation-drawer

when I'm using DrawerItemList the app crashes


I'm trying to create a drawer menu using react navigation. I want to use a custom DrawerContent, and when I'm using the the app crashes with this error: "undefined is not an object (evaluating 'state.routes')". If I comment this specific line the app just run.

This is my DrawerContent:

import {
  DrawerContentScrollView,
  DrawerItem,
  DrawerItemList,
} from "@react-navigation/drawer";
import React from "react";
import { Text, View, StyleSheet } from "react-native";

export default function DrawerContent(props) {
  return (
    <View style={{ flex: 1 }}>
      <DrawerContentScrollView
        {...props}
        contentContainerStyle={{ backgroundColor: "#000" }}
      >
      <DrawerItemList {...props} />
      </DrawerContentScrollView>
    </View>
  );
}

This is my App.js(where the navigation is):

import React from "react";
import Home from "./src/screens/Home.js";
import { NavigationContainer } from "@react-navigation/native";
import { createDrawerNavigator } from "@react-navigation/drawer";
import DrawerContent from "./src/components/DrawerContent.js";

const Drawer = createDrawerNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator
        drawerContent={() => <DrawerContent />}
        initialRouteName="Home"
      >
        <Drawer.Screen
          options={{ headerShown: false }}
          name="Home"
          component={Home}
        ></Drawer.Screen>
      </Drawer.Navigator>
    </NavigationContainer>
  );

Solution

  • You're expecting DrawerItemList to receive a full set of props from Drawer.Navigator, but you're passing it to Drawer.Navigator wrapped in a function that discards all the props it receives:

    <Drawer.Navigator
      drawerContent={() => <DrawerContent />} // <-- no props passed to DrawerContent
      initialRouteName="Home"
    >
    

    You need to pass through all props:

    <Drawer.Navigator
      drawerContent={(props) => <DrawerContent {...props} />} // <-- pass in the props
      initialRouteName="Home"
    >
    

    Note that you might think you can just pass in the function component to the prop, like this, which looks functionally identical to the above:

    <Drawer.Navigator
      drawerContent={DrawerContent} // <-- will fail with "rules of hooks" errors
      initialRouteName="Home"
    >
    

    ...but this will fail with "Invalid hook call" errors if it's a functional component that contains hooks, because drawerContent prop treats the passed-in function as a render function, not a function component.