React Native抽屉导航传参报错:route.params.eventId未定义
React Native抽屉导航跳转传参报错:TypeError: undefined is not an object (evaluating 'route.params.eventId')
问题场景
在React Native项目中,通过抽屉导航跳转到CategoryOverviewScreen并传递ID时触发错误:TypeError: undefined is not an object (evaluating 'route.params.eventId'),但通过栈导航跳转同一页面时功能正常,且抽屉导航嵌套在栈导航内部。
相关代码
EventList.js
import React from "react"; import { Pressable, StyleSheet, Text, View } from "react-native"; import { useNavigation } from "@react-navigation/native"; import color from "../../app/color"; import variables from "../../app/variables"; import { EVENT_DATA } from "../../data/category-data"; function EventList({}) { const navigation = useNavigation(); return ( <View style={styles.container}> {EVENT_DATA.map((event) => { function onPressHandler() { navigation.navigate("CategoryOverviewScreen", { eventId: event.id, }); } const eventBlock = [styles.eventBox]; if (event.id === "e7") { eventBlock.push(styles.flexEnd); } return ( <View key={event.id} style={[ eventBlock, { backgroundColor: event.color, width: event.width, height: event.height, }, ]} > <Text style={styles.title}>{event.title}</Text> <Pressable onPress={onPressHandler} style={variables.linkButton}> {event.icon} </Pressable> </View> ); })} </View> ); } export default EventList; const styles = StyleSheet.create({ container: { flex: 1, flexDirection: "row", flexWrap: "wrap", justifyContent: "space-between", }, eventBox: { padding: 10, borderRadius: 10, alignItems: "center", justifyContent: "center", borderBottomRightRadius: 0, marginBottom: 15, }, title: { fontSize: 20, color: color.white, textAlign: "center", fontFamily: "robotoMedium", }, flexEnd: { alignSelf: "flex-end", }, });
CategoryOverviewScreen.js
import { useContext } from "react"; import { ScrollView } from "react-native"; import { CATEGORY_DATA, EVENT_DATA } from "../data/category-data"; import CategoryList from "../components/CategoryList"; function CategoryOverviewScreen({ route }) { const getEeventId = route.params.eventId; const displayedCategory = CATEGORY_DATA.filter((categoryData) => { return categoryData.eventId.indexOf(getEeventId) >= 0; }); return ( <ScrollView> <CategoryList data={displayedCategory} /> </ScrollView> ); } export default CategoryOverviewScreen;
问题原因
报错核心原因:抽屉导航的CategoryOverviewScreen实例初始化时未接收任何参数。
- 栈导航通过
navigation.navigate跳转时主动传递了eventId,因此route.params存在; - 若
CategoryOverviewScreen被直接加入抽屉导航路由列表,用户通过抽屉菜单打开该页面时无参数传递,此时route.params为undefined,直接访问route.params.eventId就会触发类型错误。
解决方案
方案1:给参数添加默认值,避免访问undefined
修改CategoryOverviewScreen的参数获取逻辑,使用可选链或解构赋值带默认值,同时处理空参数过滤:
function CategoryOverviewScreen({ route }) { // 方式1:可选链+默认值 const getEeventId = route.params?.eventId || ''; // 方式2:解构赋值带默认值 // const { eventId: getEeventId = '' } = route.params || {}; const displayedCategory = CATEGORY_DATA.filter((categoryData) => { // 空参数时返回空数组,避免无效过滤 return getEeventId ? categoryData.eventId.indexOf(getEeventId) >= 0 : false; }); return ( <ScrollView> <CategoryList data={displayedCategory} /> </ScrollView> ); }
方案2:调整导航结构,避免抽屉直接加载无参页面
如果CategoryOverviewScreen不需要通过抽屉菜单直接访问,将其从抽屉导航路由配置中移除,仅保留在栈导航中,确保只有通过navigation.navigate传参的方式进入该页面。
若必须通过抽屉打开,修改抽屉导航的跳转逻辑,传递默认参数:
// 抽屉导航项的跳转处理 navigation.navigate("CategoryOverviewScreen", { eventId: '默认事件ID' });
内容的提问来源于stack exchange,提问作者Ranjit Bishwokarma
相关产品推荐
相关产品推荐

