【问题标题】:Change react navigation drawer stack based on auth. React Native根据身份验证更改反应导航抽屉堆栈。反应原生
【发布时间】:2022-01-07 13:33:15
【问题描述】:

我正在开发一个不需要用户注册的应用程序。这意味着用户即使没有注册也可以访问应用内容。我有一个抽屉导航器,如下图所示:

堆栈导航器的代码:

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>

    </>
  );
}

我想要实现的是,仅在用户未注册时才显示注册,并在用户注册时显示注销。有什么想法吗?

这是我的授权上下文代码:

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: ''}

)

【问题讨论】:

    标签: reactjs react-native react-navigation


    【解决方案1】:

    检查您的令牌(或用户数据)。然后使用选择器访问值(或您用来访问数据的任何方法)并使用条件渲染:

    const isLoggedIn = ...your logic to detect logged in status ...
    
    {isLoggedIn 
      ? <Drawer.Screen name={t('Register')} component={Register}/> : 
      : <Drawer.Screen name={t('Logout')} component={Logout}/> }
    

    【讨论】:

    • 我做了什么:const { state } = useContext(AuthContext); {state.token === false ? &lt;Drawer.Screen name={t('Register')} component={Register}/&gt; : null } 现在这工作但仍然没有删除它,因为我也有自定义抽屉组件,它从那里读取它
    【解决方案2】:

    您可以使用 react-navigation v6 中引入的 Group,您可以在导航之上创建自定义上下文并根据上下文值做出决定。

    文档链接:https://reactnavigation.org/docs/group/

    例如

     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>
     )
    

    【讨论】:

      【解决方案3】:

      它看起来在你的项目中使用 redux 包。 只需在抽屉组件中使用 redux 的 useSelector 即可获取注册状态。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-21
        • 1970-01-01
        • 1970-01-01
        • 2021-03-04
        • 2020-09-03
        • 1970-01-01
        • 2021-07-30
        相关资源
        最近更新 更多