简体   繁体   中英

Change react navigation drawer stack based on auth. React Native

Im working on an app in which user registration is not required. That means that the users can access the app content even if they havent registered. I have a drawer navigator like this photo below: 在此处输入图像描述

The code for the stack navigator:

function AppStack(props) {
  const { state } = useContext(AuthContext);
  return (
    <><Drawer.Navigator
      style={{ flex: 1 }}
      drawerContent={props => <CustomDrawerContent {...props} />}
      drawerStyle={{
        backgroundColor: nowTheme.COLORS.PRIMARY,
        width: width * 0.65,

      }}
      drawerContentOptions={{
        activeTintcolor: nowTheme.COLORS.WHITE,
        inactiveTintColor: nowTheme.COLORS.WHITE,
        activeBackgroundColor: "transparent",
        itemStyle: {
          width: width * 0.75 ,
          backgroundColor: "transparent",
          paddingVertical: 16,
          paddingHorizonal: 12,
          justifyContent: "center",
          alignContent: "center",
          alignItems: "center",
          overflow: "hidden"
        },
        labelStyle: {
          fontSize: 18,
          marginLeft: 12,
          fontWeight: "normal"
        }
      }}
      initialRouteName="Home"
    >
      
      <Drawer.Screen name={t('Home')} component={HomeStack} />
      <Drawer.Screen name={t('News')} component={ArticlesStack} />
      <Drawer.Screen name={t('Profile')} component={ProfileStack} />
       <Drawer.Screen name={t('Register')} component={Register}/>
      <Drawer.Screen name={t('Settings')} component={SettingsStack} />
      
      <Drawer.Screen name={t('Start Evaluation')} component={EvaluationsStack} />
    </Drawer.Navigator>

    </>
  );
}

What i want to achieve is that the Register to show only when the user is not registered and logout to show when the user registers. Any ideas for that?

Here is my auth context code:

import createDataContext from "./createDataContext";
import authApi from "../../api/authApi";
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as RootNavigation from '../../auth/navigationRef';



const authReducer = (state, action) => {
  switch (action.type) {
    case 'add_error':
      return {...state, errorMessage: action.payload };
    case 'signup' :
      return  {errorMessage: '', token: action.payload };
    case "signin":
      return { errorMessage: "", token: action.payload };
    case 'clear_error_message':
      return {...state, errorMessage: ''};
    case 'signout': 
      return {token: null, errorMessage: ''}
    default:
      return state;
  }
};

const tryLocalSignin = dispatch => async () => {
  const token = await AsyncStorage.getItem('token');
  if (token) {
    dispatch({ type: 'signin', payload: token  });
    RootNavigation.navigate('App');
  } else {
    RootNavigation.navigate('Register');
  }
}

const clearErrorMessage = dispatch => () => {
  dispatch({type: 'clear_error_message'});
}

const signup = dispatch => async ({email, password, name}) => {
    try {
      const response = await authApi.post('/signup', {email, password, name});
      await AsyncStorage.setItem('token', response.data.token);
      dispatch({ type: 'signup', payload: response.data.token});

      RootNavigation.navigate('Onboarding');
    } catch (error) {
      console.log(error)
      dispatch({type: 'add_error', payload: 'Something went wrong with sign up'})
    }
  };


const signin = dispatch => async ({email, password}) => {
  try {
     const response = await authApi.post('/signin', {email, password});
     await AsyncStorage.setItem('token', response.data.token);
     dispatch({type: 'signin', payload: response.data.token});
     RootNavigation.navigate('App');
  } catch (error) {
    console.log(error)
    dispatch({
      type: 'add_error',
      payload: 'Something went wrong with sign in'
    })
  }
};

const signout = dispatch => async () => {
  await AsyncStorage.removeItem('token');
  dispatch({type: 'signout'});
  RootNavigation.navigate('Auth');
}

export const {Provider , Context} = createDataContext(
  authReducer,
  {signin, signup, signout, clearErrorMessage, tryLocalSignin, addQuest},
  {token: false, errorMessage: ''}

)

Check for your token (or user data). Then use a selector to access the value (or whatever method you use to access data) and use conditional rendering:

const isLoggedIn = ...your logic to detect logged in status ...

{isLoggedIn 
  ? <Drawer.Screen name={t('Register')} component={Register}/> : 
  : <Drawer.Screen name={t('Logout')} component={Logout}/> }

You can use Group introduced in react-navigation v6 and you can create a custom context on top of your navigation and make a decision based on context values.

Link to doc: https://reactnavigation.org/docs/group/

For eg

 const { isLoggedIn } = useContext(LogicContext); // any logic here

 return(
   <Drawer.Group>
       { isLoggedIn ? <Drawer.Screen name="LoggedInDrawer" component={LoggedInDrawer} /> :  <Drawer.Screen name="LoggedOutDrawer" component={LoggedOutDrawer} />
   </Drawer.Group>
 )

It looks to use redux package in your project. Just you can get registerration state by using useSelector of redux in the drawer component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM