如何将 onPress 事件监听器添加到 React Native React 导航中的抽屉导航项?

问题描述 投票:0回答:2

我按以下方式配置了抽屉导航:

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

javascript react-native react-navigation react-navigation-drawer react-navigation-v6
2个回答
0
投票

要将注销按钮添加到客户抽屉,请创建自定义抽屉。

这是来自实际项目的完整示例。

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;

0
投票

我在德国科卡问题中的第一个链接中找到了我的工作解决方案,来自这个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>
        );
    };
© www.soinside.com 2019 - 2024. All rights reserved.