如何在react native react导航中向抽屉式导航项添加onPress事件侦听器?

uqjltbpv  于 2023-04-22  发布在  React
关注(0)|答案(1)|浏览(151)

我有一个抽屉导航配置如下:

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 props传递给drawer navigator,就像文档说的那样(下面的例子),所有其他屏幕都不再呈现,这也不是我想要的。
<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

r7knjye2

r7knjye21#

要向客户抽屉添加注销按钮,请创建自定义抽屉。
下面是一个来自实时项目的完整示例。

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;

相关问题