React Native自定义抽屉导航报错:navigation.closeDrawer未定义
我是React Native新手,正在尝试创建自定义抽屉导航,想要在抽屉内部添加一个关闭抽屉的按钮,但始终遇到错误:TypeError: undefined is not an object (evaluating 'navigation.closeDrawer')。以下是我的代码:
import React, { useState } from "react"; import {DrawerActions} from '@react-navigation/native'; import Logo from '../assets/images/Logo.png' import { View, Text, Image, TouchableOpacity, ScrollView } from 'react-native'; import { createDrawerNavigator, DrawerContentScrollView, } from '@react-navigation/drawer'; import { MainLayout } from "../screens"; import { COLORS, FONTS, SIZES, constants, icons, dummyData, } from '../constants'; import Animated from "react-native-reanimated"; const Drawer = createDrawerNavigator() const CustomDrawerItem = ({label, icon}) => { return ( <TouchableOpacity style={{ flexDirection: 'row', height: 40, marginBottom: SIZES.base, alignItems: 'center', paddingLeft: SIZES.radius, borderRadius: SIZES.base }} > <Image source={icon} style={{ width: 20, height: 20, tintColor: COLORS.primary }}/> <Text style={{ marginLeft: 15, color: COLORS.primary, ...FONTS.h3 }} > {label} </Text> </TouchableOpacity> ) } const CustomDrawerContent = ({ navigation }) => { return ( <DrawerContentScrollView scrollEnbled={true} contentContainerStyle={{ flex: 1}} > <ScrollView style={{ flex: 1, paddingHorizontal: SIZES.radius }} > {/* Logo*/} <TouchableOpacity style = {{ flexDirection: 'row', marginTop: SIZES.radius, alignItems: 'center', marginBottom: 20, }}> <Image style={{ flex: 1, width: 80, height: 80, resizeMode: 'contain', marginLeft: -60, }} source={Logo}/> <View style={{ marginLeft: SIZES.radius }} > <View style={{ alignItems: 'flex-end', justifyContent: 'center' }} > <TouchableOpacity style={{ alignItems: 'center', justifyContent: 'center', tintColor: COLORS.black }} onPress={() => navigation.closeDrawer()} > <Image source={icons.cross} style={{ height: 25, width: 25, }} /> </TouchableOpacity> </View> </View> </TouchableOpacity> {/* Profile */} <TouchableOpacity style = {{ flexDirection: 'row', marginTop: SIZES.radius, alignItems: 'center' }}> <View style={{ marginLeft: SIZES.radius }} > <CustomDrawerItem icon={icons.profile} label={constants.sideBarElements.guest} /> <View> {dummyData.GuestData.map( (item, index) => ( <Text style={{ paddingLeft: 20, paddingTop: 10, color: COLORS.gray }}> {item.name} </Text> ) )} </View> </View> </TouchableOpacity> {/* Line devider <View style={{ height: 1, marginVertical: SIZES.radius, //marginLeft: SIZES.radius, backgroundColor: COLORS.lightGray1 }} />*/} {/* Drawer Items */} <View style={{ flex: 1, marginTop: SIZES.padding, marginLeft: SIZES.radius }} > <CustomDrawerItem icon={icons.cart} label={constants.sideBarElements.store} /> <View> {dummyData.storesData.map( (item, index) => ( <Text style={{ paddingLeft: 20, paddingTop: 10, color: COLORS.gray }}> {item.title} </Text> ) )} </View> </View> <View style={{ flex: 1, marginTop: SIZES.padding, marginLeft: SIZES.radius, marginBottom: 50 }} > <CustomDrawerItem icon={icons.cart} label={constants.sideBarElements.categories} /> <View> {dummyData.carouselData.map( (item, index) => ( <Text style={{ paddingLeft: 20, paddingTop: 10, color: COLORS.gray }}> {item.category} </Text> ) )} </View> </View> </ScrollView> </DrawerContentScrollView> ) } const CustomDrawer = () => { const [progress, setProgress] = useState(new Animated.Value(0)) const scale = Animated.interpolateNode(progress, { inputRange: [0, 1], outputRange: [1, 0.8] }) const borderRadius = Animated.interpolateNode(progress, { inputRange: [0, 1], outputRange: [0, 26] }) const animatedStyles = {borderRadius, transform: [{scale}]} return ( <View style={{ flex: 1, backgroundColor: COLORS.primary }} > <Drawer.Navigator drawerType='slide' overlayColor='transparent' drawerStyle={{ flex: 1, width: '65%', paddingRight: 20, backgroundColor: 'transparent' }} sceneContainerStyle={{ backgroundColor: 'transparent' }} initialRouteName='MainLayout' drawerContent={props => { setTimeout(()=> { setProgress(props.progress) }, 0) return ( <CustomDrawerContent navigration ={props.navigation} /> ) }} > <Drawer.Screen name='MainLayout'> {props => <MainLayout {...props} drawerAnimationStyle={animatedStyles}/>} </Drawer.Screen> </Drawer.Navigator> </View> ) } export default CustomDrawer;
我甚至尝试过使用dispatch,但仍出现相同错误,不清楚问题出在哪里。
问题原因及修复方案
问题出在属性名拼写错误:在CustomDrawer组件的drawerContent回调中,你传递给CustomDrawerContent的属性名写成了navigration(多了一个i),而CustomDrawerContent接收的是navigation,导致navigation参数为undefined,调用closeDrawer()时就会报错。
修复代码:
找到drawerContent中的这段代码:
return ( <CustomDrawerContent navigration ={props.navigation} /> )
将属性名修正为navigation:
return ( <CustomDrawerContent navigation={props.navigation} /> )
可选替代方案
如果后续仍有问题,可以尝试使用DrawerActions来触发关闭抽屉的动作,确保已导入DrawerActions:
// 在CustomDrawerContent的关闭按钮 onPress 中替换为: onPress={() => navigation.dispatch(DrawerActions.closeDrawer())}
内容的提问来源于stack exchange,提问作者Ons Jannet
相关产品推荐
相关产品推荐

