我已经使用所有常用的身份验证选项设置了我的 React Native 项目。然后我设置了抽屉导航,并且可以在所有身份验证屏幕和主屏幕之间成功导航。
当用户已经登录时,让
Login
选项占用菜单上的空间是没有意义的,因此我尝试使用上下文根据登录状态隐藏它。上下文工作正常,但现在当我尝试导航回上一页时,登录后会出现错误。 ERROR The action 'GO_BACK' was not handled by any navigator. Is there any screen to go back to?
这是一个仅在开发中出现的错误,不会出现在生产中,但我认为有一种方法可以做到这一点,不会导致错误,并且会返回到上一个屏幕而不是初始屏幕。
这是我的代码,以防我实际上做错了。 NavMenu.js
import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import HomeScreen from './HomeScreen';
import IndexBooks from './books/IndexBooks';
import IndexSeries from './series/IndexSeries';
import LoginScreen from './auth/LoginScreen';
import LogoutScreen from './auth/LogoutScreen';
import RegisterScreen from './auth/RegisterScreen';
import ResetPasswordScreen from './auth/ResetPasswordScreen';
import { AuthContext } from './auth/AuthCentext';
const Drawer = createDrawerNavigator();
export default function NavMenu() {
const { user } = React.useContext(AuthContext);
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName='Home'
>
<Drawer.Screen
name="Home"
component={HomeScreen}
/>
<Drawer.Screen
name="Books"
component={IndexBooks}
options={{ title: 'Books' }}
/>
<Drawer.Screen
name="Series"
component={IndexSeries}
options={{ title: 'Reading Lists' }}
/>
{/* {user == null && */}
<Drawer.Screen
name="Login"
component={LoginScreen}
/>
{/* } */}
{user == null &&
<Drawer.Screen
name="Register"
component={RegisterScreen}
/>
}
{user !== null &&
<Drawer.Screen
name="Logout"
component={LogoutScreen}
/>
}
{user !== null &&
<Drawer.Screen
name="Reset Password"
component={ResetPasswordScreen}
/>
}
</Drawer.Navigator>
</NavigationContainer>
);
}
登录屏幕.js
// send the login request
const handleLogin = async () => {
try {
const response = await axios.post('/api/login', {
email: email,
password: password,
device_name: 'mobile',
});
// on success add the token to axios defaults for future requests
const csrfToken = response.data.token;
const user = response.data.user.id.toString();
axios.defaults.headers.common['Authorization'] = `Bearer ${csrfToken}`;
// then save it for use in future app sessions and return to previous screen
try {
AsyncStorage.setItem('user', user);
await AsyncStorage.setItem('csrfToken', csrfToken);
setUser(user);
navigation.goBack();
} catch (e) {
console.log('error', e);
}
} catch (error) {
console.log(error);
Alert.alert('Login Failed', 'Please check your credentials and try again.');
}
};
如何才能在不产生错误的情况下完成此操作?
我终于在这个示例中找到了答案,这让我找到了我错过的抽屉导航器文档。抽屉导航器组件允许您完全覆盖抽屉内容并使用属性
drawerContent
添加自己的内容.
import React, { useContext } from 'react';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createDrawerNavigator, DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer';
export default function NavMenu() {
const { user } = useContext(AuthContext);
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName='Home'
drawerContent={(props) => (
<CustomDrawerContent {...props} />
)}
>
<Drawer.Screen
name="Home"
component={HomeScreen}
/>
<Drawer.Screen
name="Login"
component={LoginScreen}
/>
<Drawer.Screen
name="Logout"
component={LogoutScreen}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
默认情况下,自定义内容无权访问
navigation
,但您可以使用 useNavigation
授予其访问权限。
import React, { useContext } from 'react';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createDrawerNavigator, DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer';
const CustomDrawerContent = (props) => {
const navigation = useNavigation();
const { user } = useContext(AuthContext);
console.log('user', user);
return (
<DrawerContentScrollView {...props}>
<DrawerItem
label="Home"
onPress={() => navigation.navigate('Home')}
/>
{user === null &&
<DrawerItem
label="Log In"
onPress={() => navigation.navigate('Login')}
/>
}
{user !== null &&
<DrawerItem
label="Log Out"
onPress={() => navigation.navigate('Logout')}
/>
}
</DrawerContentScrollView>
);
}