我按以下方式配置了抽屉导航:
const CustomDrawerContent = () => { return ( <DrawerItem label="Log out2" onPress={() => logOut()} /> ) }
const loginStack = () => (
<Stack.Navigator >
<Stack.Screen name='LandingScreen' component={LandingScreen} options={{headerShown: false}} />
<Stack.Screen name='LoginScreen' component={LoginScreen} options={{headerShown: false}} />
<Stack.Screen name='RegisterScreen' component={RegisterScreen} options={{headerShown: false}} />
</Stack.Navigator>
)
return (
<NavigationContainer>
<Drawer.Navigator
screenOptions={{
drawerStyle: { backgroundColor: 'white' },
drawerPosition: 'right'
}}>
{!user ? (
<Drawer.Screen
name="PublicStack"
component={loginStack}
options={{headerShown: false}}
/> )
:
(<>
<Drawer.Screen name='Search cocktails' component={HomeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Profile' component={ProfileScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Publish a recipe' component={PublishRecipeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Favorites' component={FavoritesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Published recipes' component={PublishedRecipesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Log out' component={CustomDrawerContent} options={{ header: () => <Header/> }} />
<Drawer.Screen name='CocktailDetailScreen' component={CocktailDetailScreen} options={{
header: () => <Header/>,
drawerLabel: () => null,
title: undefined
}} />
</>
)}
</Drawer.Navigator>
</NavigationContainer>
)
所有屏幕都工作正常,但我希望
Log out
在按下时执行注销功能。据我了解,我无法直接在屏幕组件上添加此事件侦听器,因此我遵循了此文档(https://reactnavigation.org/docs/drawer-navigator/#drawercontent)并尝试了一些不同的操作:
CustomDrawerContent
,它是一个 DrawerItem
。CustomDrawerContent
作为组件传递到 Log out
屏幕(正如代码现在所示),当我单击它时,我会被重定向到呈现 CustomDrawerContent
组件的空白页面,这不是我想要的想要。CustomDrawerContent
作为 drawerContent
道具传递给抽屉导航器,就像文档所说的那样(下面的示例),所有其他屏幕都不再渲染,这又不是我想要的。<Drawer.Navigator drawerContent={(props) => <CustomDrawerContent />}>
{/* screens */}
</Drawer.Navigator>
useNavigationBuilder.tsx:134 Uncaught Error: A navigator can only contain 'Screen', 'Group' or 'React.Fragment' as its direct children (found 'DrawerItem'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
那么如何将项目添加到抽屉中而不“覆盖”屏幕呢? 或者有其他方法可以在抽屉里放一个简单的注销按钮吗?
完整代码可以在这里找到:https://github.com/coccagerman/mixr
要将注销按钮添加到客户抽屉,请创建自定义抽屉。
这是来自实际项目的完整示例。
import { DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer';
import React from 'react';
import { Image, StyleSheet, Text, View } from 'react-native';
import { useSelector } from 'react-redux';
import { logsout } from '../../utils/helpers';
export function CustomDrawer(props) {
const user = useSelector(state => state.user)
return (
<View style={styles.container}>
<View style={styles.drawHead}>
<Text style={styles.name}>
{user?.lname} {user?.fname}
</Text>
</View>
<DrawerContentScrollView {...props} contentContainerStyle={styles.s}>
<DrawerItem label={'Dashboard'} onPress={() => props.navigation.navigate('UserDashboard')} />
<DrawerItem label={'Profile'} onPress={() => props.navigation.navigate('profile')} />
<DrawerItem label={'Notifications'} onPress={() => props.navigation.navigate('notifications')} />
<DrawerItem label={'Logout'} onPress={() => {
async function load() { await logsout() }
load()
}} />
</DrawerContentScrollView>
<Image
style={styles.footLogo}
source={require('../../assets/logo-dark.png')}
/>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
drawHead: {
display: 'flex',
height: 180,
backgroundColor: 'black',
marginBottom: 20,
paddingStart: 20,
paddingTop: '22%',
},
name: {
fontSize: 24,
fontFamily: 'poppins-Regular',
color: 'white'
},
s: {
flex: 1,
paddingStart: 10,
},
footLogo: {
width: 60,
height: 35,
marginStart: 20,
marginTop: 20,
marginBottom: 10,
alignSelf: 'flex-start',
resizeMode: 'contain',
}
});
此处的
logout
调度 redux 操作来注销用户。使用您自己的实现。
然后使用抽屉导航器中的
customDrawer
:
import * as React from 'react';
import UserDashboard from '../pages/user/dasboard';
import Profile from '../pages/user/profile';
import Notifications from '../pages/user/notifications';
import { CustomDrawer } from '../pages/user/customDrawer';
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator()
const UserStack = () => {
const pages = [
{ name: "UserDashboard", comp: UserDashboard },
{ name: "profile", comp: Profile },
{ name: "notifications", comp: Notifications },
]
return (
<Drawer.Navigator
initialRouteName='UserDashboard'
drawerContent={(props) => <CustomDrawer {...props} />}
screenOptions={({ route }) => ({
activeTintColor: '#8772BC',
headerShown: false,
})}>
{pages.map(page =>
<Drawer.Screen
key={page.name}
name={page.name}
component={page.comp} />
)}
</Drawer.Navigator>
);
};
export default UserStack;
我在德国科卡问题中的第一个链接中找到了我的工作解决方案,来自这个Snack
import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem } from '@react-navigation/drawer';
const CustomDrawerContent = (props) => {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem label="Logout" onPress={() => handleLogout()} />
</DrawerContentScrollView>
);
}
const ProductListWithDrawer = () => {
return (
<Drawer.Navigator
initialRouteName="ProductList"
useLegacyImplementation
// **** LINE BELOW ADDS Your Custom DrawerItems TO THE DRAWER SCREEN LIST *****
drawerContent={(props) => <CustomDrawerContent {...props} />}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Chat" component={ChatScreen} />
<Drawer.Screen name="Search" component={SearchScreen} />
</Drawer.Navigator>
);
};