0

anyone here that can share an example on how to implement a Stack navigator for unprotected routes and a Drawer navigator for protected routes ?

I have done this but, its not functional at all.. Quite new to this, please help

// Navigation Components
import DrawerNavigator from './DrawerNavigator';
import StackNavigator from './StackNavigator';

const AppNav = () => {
  const [Auth, setAuth] = useState(null);

  useEffect(() => {
    const checkAuth = async () => {
      const token = await getToken();
      console.log('token AppNav: ', token);
      if (token) {
        setAuth(true);
      } else {
        setAuth(false);
      }
    };
    checkAuth();
  }, []);

  const Routes = [
    {
      name: 'Home',
      component: Home,
      isAuth: true,
    },
    {
      name: 'Login',
      component: Login,
      isAuth: false,
    },
    {
      name: 'OTPScreen',
      component: OTPScreen,
      isAuth: false,
    },
    {
      name: 'ResetPassword',
      component: ResetPassword,
      isAuth: false,
    },
    {
      name: 'SignUp',
      component: SignUp,
      isAuth: false,
    },
  ];

  return (
    <NavigationContainer>
      {Auth ? <DrawerNavigator routes={Routes} /> : <StackNavigator routes={Routes} />}
    </NavigationContainer>
  );
};

export default AppNav;

Drawer Navigator

import React from 'react';
import { createDrawerNavigator } from '@react-navigation/drawer';
import PropTypes from 'prop-types';

// Utils
import { uniqueId } from '../common/utils';

const Drawer = createDrawerNavigator();

const DrawerNavigator = ({ routes }) => {
  const authRoutes = routes.filter((route) => route.isAuth);
  return (
    <Drawer.Navigator screenOptions={{ headerShown: false }}>
      {authRoutes.map((route) => (
        <Drawer.Screen key={uniqueId('drawer')} name={route.name} component={route.component} />
      ))}
    </Drawer.Navigator>
  );
};

DrawerNavigator.propTypes = {
  routes: PropTypes.arrayOf(PropTypes.object).isRequired,
};

export default DrawerNavigator;

Stack Navigator



import React from 'react';
import PropTypes from 'prop-types';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

// Utils
import { uniqueId } from '../common/utils';

const Stack = createNativeStackNavigator();

const StackNavigator = ({ routes }) => (
  <Stack.Navigator screenOptions={{ headerShown: false }}>
    {routes.map((route) => (
      <Stack.Screen key={uniqueId('navigator')} name={route.name} component={route.component} />
    ))}
  </Stack.Navigator>
);

StackNavigator.propTypes = {
  routes: PropTypes.arrayOf(PropTypes.object).isRequired,
};

export default StackNavigator;

the biggest issue that I have with this solution of mine is that, it can find routes from the Stack Navigator if you are logged in. so if you want to use navigation.navigate in a logout function to direct the user to the login screen again it says the following

The action 'NAVIGATE' with payload {"name":"Login"} was not handled by any navigator.

Do you have a screen named 'Login'?

If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.

This is a development-only warning and won't be shown in production.

And it always goes to the home screen even if the token is null, I know for a sure fact I am not doing this right and I dont know where to turn to get it working as it should.

Faziki
  • 767
  • 1
  • 9
  • 24

1 Answers1

0

you only rely on usestate, and once the user is logout, the auth value not change, that's why you need global global state management like redux or context

const [Auth, setAuth] = useState(null);

check this thread Accessing Context in React Native

sample part of context

import React from 'react';
import { View, Text, Button } from 'react-native';
import { useMain } from './context/Context';

const Child = () => {
  const { dummy, setDummy } = useMain();
  const onPressLearnMore = () => {
    setDummy('c');
  };
  return (
    <View>
      <Text>This children {dummy}</Text>
      <Button onPress={onPressLearnMore} title="click" />
    </View>
  );
};

export default Child;
 
bagi2info.com
  • 408
  • 1
  • 3
  • 11