Home > front end >  can not read property 'openDrawer' of undefined
can not read property 'openDrawer' of undefined

Time:01-12

i started to learn react native and i am getting error because i cant use openDrawer and i don't know where is the error. i tried to follow the instructions on the react navigation web page.

below is my code

MainHeader

import React from 'react';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Icon from '../../utils/Icon';
import {View} from 'react-native';
import {spacing} from '../../constants/theme';

const MainHeader = ({navigation}) => {
  const insets = useSafeAreaInsets();
  return (
    <View
      style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignContent: 'center',
        paddingHorizontal: spacing.l,
        marginTop: insets.top,
      }}>
      <Icon icon="Hamburger" onPress={() => navigation.openDrawer()} />
      <Icon style={{width: 25, height: 25}} icon="Cart" onPress={() => {}} />
    </View>
  );
};

export default MainHeader;

MainNavigator

import React from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import {NavigationContainer} from '@react-navigation/native';
import {StatusBar} from 'react-native';
import TabNavigator from './TabNavigator';

const Stack = createStackNavigator();
const MainNavigator = () => {
  return (
    <NavigationContainer>
      <StatusBar hidden />
      <Stack.Navigator>
        <Stack.Screen
          name="Root"
          component={TabNavigator}
          options={{
            headerShown: false,
            useNativeDriver: true,
            gestureEnabled: false,
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default MainNavigator;

TabNavigator

import React from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {Animated} from 'react-native';
import Icon from '../utils/Icon';
import {colors, sizes} from '../constants/theme';
import PromoScreen from '../screens/PromoScreen';
import HomeNavigator from './HomeNavigator';
import ProductNavigator from './ProductNavigator';
import SearchNavigator from './SearchNavigator';
import ProfileNavigator from './ProfileNavigator';
import LoginScreen from '../screens/LoginScreen';

const tabs = [
  {
    name: 'Home',
    screen: HomeNavigator,
  },
  {
    name: 'Coffee',
    screen: ProductNavigator,
  },
  {
    name: 'Search',
    screen: SearchNavigator,
  },
  {
    name: 'Gift',
    screen: PromoScreen,
  },
  {
    name: 'Profile',
    screen: LoginScreen,
  },
];
const Tab = createBottomTabNavigator();
const TabNavigator = () => {
  const offsetAnimation = React.useRef(new Animated.Value(0)).current;
  return (
    <>
      <Tab.Navigator
        initialRouteName="Home"
        screenOptions={{
          headerShown: false,
          tabBarShowLabel: false,
        }}>
        {tabs.map(({name, screen}, index) => {
          return (
            <Tab.Screen
              key={name}
              name={name}
              component={screen}
              options={{
                tabBarIcon: ({focused}) => {
                  return (
                    <Icon
                      icon={name}
                      size={40}
                      style={{
                        tintColor: focused ? colors.mainColor : colors.gray,
                      }}
                    />
                  );
                },
              }}
              listeners={{
                focus: () => {
                  Animated.spring(offsetAnimation, {
                    toValue: index * (sizes.width / tabs.length),
                    useNativeDriver: true,
                  }).start();
                },
              }}
            />
          );
        })}
      </Tab.Navigator>
    </>
  );
};

export default TabNavigator;

DrawNavigator

import React from 'react';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {NavigationContainer} from '@react-navigation/native';
import HomeNavigator from './HomeNavigator';

const Drawer = createDrawerNavigator();
const MainDrawNavigator = () => {
  return (
    <NavigationContainer>
      <Drawer.Navigator initialRouteName="Home">
        <Drawer.Screen name="Home" component={HomeNavigator} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
};

export default MainDrawNavigator;

Home Navigator

import React from 'react';
import {createSharedElementStackNavigator} from 'react-navigation-shared-element';
import HomeScreen from '../screens/HomeScreen';

const Stack = createSharedElementStackNavigator();
const HomeNavigator = () => {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="HomeScreen"
        component={HomeScreen}
        options={{
          headerShown: false,
          useNativeDriver: true,
          gestureEnabled: false,
        }}
      />
    </Stack.Navigator>
  );
};
export default HomeNavigator;

HomeScreen

import React from 'react';
import {ScrollView, View} from 'react-native';
import MainHeader from '../components/Header/MainHeader';
import TitleHeader from '../components/Header/TitleHeader';
import MenuSlider from '../components/Home/MenuSlider';
import {Top_Sell, POPULAR} from '../data';
import SectionHeader from '../components/Header/SectionHeader';
import PopularList from '../components/Home/PopularList';

const HomeScreen = () => {
  return (
    <View style={{flex: 1, backgroundColor: '#fbfbfb'}}>
      <MainHeader />
      <TitleHeader mainTitle="Gợi ý" secondTitle="cho bạn" />
      <ScrollView showsVerticalScrollIndicator={false}>
        <MenuSlider list={Top_Sell} />
        <SectionHeader title="Phổ biến" buttonTitle="More" onPress={() => {}} />
        <PopularList list={POPULAR} />
      </ScrollView>
    </View>
  );
};

export default HomeScreen;

I have tried several ways on stackOverflow but it doesn't work

CodePudding user response:

You need to pass the navigation prop from HomeScreen to MainHeader to use it. Try replacing your HomeScreen with this:

const HomeScreen = ({ navigation }) => {
  return (
    <View style={{flex: 1, backgroundColor: '#fbfbfb'}}>
      <MainHeader navigation={navigation} />
      <TitleHeader mainTitle="Gợi ý" secondTitle="cho bạn" />
      <ScrollView showsVerticalScrollIndicator={false}>
        <MenuSlider list={Top_Sell} />
        <SectionHeader title="Phổ biến" buttonTitle="More" onPress={() => {}} />
        <PopularList list={POPULAR} />
      </ScrollView>
    </View>
  );
};

CodePudding user response:

please try this one. it seems that there is some issue with navigation state. check this one it will work.

based on your comment you may forgot to install some packages that are mandatory without that navigation won't work properly.

Please check for these.

@react-navigation/drawer,
@react-navigation/native-stack,
react-native-gesture-handler,
react-native-screens,
react-native-pager-view
[react-native-reanimated][1]

first configure these library , clean your project, delete it from device , rebuild and cheers!!

then. try this one

import React from 'react';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Icon from '../../utils/Icon';
import {View} from 'react-native';
import {spacing} from '../../constants/theme';
import { useNavigation } from '@react-navigation/native';
const MainHeader = ({}) => {
  const navigation = useNavigation();
  const insets = useSafeAreaInsets();
  return (
    <View
      style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignContent: 'center',
        paddingHorizontal: spacing.l,
        marginTop: insets.top,
      }}>
      <Icon icon="Hamburger" onPress={() => navigation.openDrawer()} />
      <Icon style={{width: 25, height: 25}} icon="Cart" onPress={() => {}} />
    </View>
  );
};

export default MainHeader;
  • Related