React Native传递函数参数为undefined问题排查求助
解决React Native导航传参导致函数undefined的问题
问题根源
- 导航传参方式错误:你在
App.js的Tab.Screen中把confOnClick和teamData放在options里,而options是用于配置导航栏样式的,并非传递页面参数的正确位置。 - 页面组件未正确获取参数:
Team.js直接尝试解构confOnClick和teamData,但这些参数实际存在于路由的route.params中,而非组件的直接props。 - Category.js代码粘贴错误:你提供的
Category.js内容和Team.js完全重复,正确的Category组件应该包含触发点击的按钮元素。
修正步骤及代码
1. 修改App.js:用initialParams传递参数
将Tab.Screen的options替换为initialParams,这是React Navigation向页面组件传递初始参数的正确方式:
import React, {useState} from 'react'; import {View, Text, StyleSheet, FlatList, Alert} from 'react-native'; import {NavigationContainer} from '@react-navigation/native'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import {v4 as uuid} from 'uuid'; import 'react-native-get-random-values'; import Team from './pages/Team'; import Header from './components/Header'; import Home from './pages/Home'; import axios from 'axios'; const App = () => { const [teamData, setTeamData] = useState([]); const [confIndex, setConfIndex] = useState(); function SettingsScreen() { return ( <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}> <Text>Settings!</Text> </View> ); } const Tab = createBottomTabNavigator(); const confOnClick = async text => { console.log(text); if (text === 'East') { setConfIndex(0); } else { setConfIndex(1); } const options = { method: 'GET', url: 'https://api-nba-v1.p.rapidapi.com/teams', params: {conference: text}, headers: { 'X-RapidAPI-Key': '你的API密钥', // 替换为实际密钥 'X-RapidAPI-Host': 'api-nba-v1.p.rapidapi.com', }, }; try { const response = await axios.request(options); console.log(response.data.response); setTeamData(response.data.response); } catch (error) { console.error(error); } }; return ( <View style={styles.container}> <Header /> <NavigationContainer> <Tab.Navigator screenOptions={{headerShown: false}}> <Tab.Screen name="Home" component={Home} /> <Tab.Screen name="Team" component={Team} initialParams={{confOnClick: confOnClick, teamData: teamData}} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> </NavigationContainer> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, }); export default App;
2. 修改Team.js:从route.params中获取参数
组件需要通过route.params获取传递的参数,同时添加默认值避免undefined:
import React from 'react'; import {View, StyleSheet, FlatList} from 'react-native'; import ListItem from '../components/ListItem'; import Category from '../components/Category'; function Team({route}) { const {confOnClick, teamData} = route.params || {}; return ( <View style={styles.container}> <Category confOnClick={confOnClick} /> <FlatList data={teamData} renderItem={({item}) => <ListItem item={item} />} keyExtractor={(item) => item.id.toString()} // 添加keyExtractor避免警告 /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 10, }, }); export default Team;
3. 修正Category.js:添加按钮触发点击
重新编写Category组件,包含东西部按钮,调用传递来的confOnClick:
import React from 'react'; import {View, StyleSheet, TouchableOpacity, Text} from 'react-native'; function Category({confOnClick}) { return ( <View style={styles.container}> <TouchableOpacity style={styles.button} onPress={() => confOnClick?.('East')} // 可选链避免调用undefined函数 > <Text style={styles.buttonText}>东部球队</Text> </TouchableOpacity> <TouchableOpacity style={styles.button} onPress={() => confOnClick?.('West')} > <Text style={styles.buttonText}>西部球队</Text> </TouchableOpacity> </View> ); } const styles = StyleSheet.create({ container: { flexDirection: 'row', justifyContent: 'space-around', padding: 10, marginBottom: 10, }, button: { backgroundColor: '#1E90FF', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 5, }, buttonText: { color: '#fff', fontSize: 16, }, }); export default Category;
额外优化建议
- 用
try/catch替代.then/.catch,让异步代码更简洁可读。 - 给FlatList添加
keyExtractor,避免React Native的警告。 - 在调用
confOnClick时使用可选链?.,即使参数未传递也不会报错。
内容的提问来源于stack exchange,提问作者Lau Ricky
相关产品推荐
相关产品推荐

