如何修复TypeError: undefined is not an object (evaluating 'userData.username')错误
修复React Native应用中SearchUserPage的TypeError并实现同城市随机用户展示功能
问题概述
开发的React Native应用中,用户登录后主页面授权获取城市并保存到MongoDB的功能正常,但进入SearchUserPage页面时,出现TypeError: undefined is not an object (evaluating 'userData.username')错误,需实现展示同城市随机用户的用户名和头像功能并修复该错误。
错误原因分析
- SearchUserPage未初始化用户数据:当前页面未获取用户信息或后端返回的随机用户数据,直接访问
userData.username导致undefined报错。 - 后端GET接口参数获取错误:GET请求无法通过
req.body获取参数,后端/user接口用req.body.city会导致city为undefined,进而查询不到用户。 - 前端未发起请求获取随机用户:SearchUserPage没有请求后端接口获取同城市的随机用户数据。
修复与实现步骤
1. 修复后端GET接口
将/user接口的参数获取方式从req.body.city改为req.query.city,因为GET请求的参数在URL查询字符串中:
router.get("/user", async (req, res) => { try { // 改为从query获取city参数 const city = req.query.city; if (!city) { return res.status(400).json({ error: "City parameter is required" }); } console.log(city); const count = await User.countDocuments({ city: city }); if (count === 0) { return res.status(404).json({ error: "No users found with that city" }); } const randomUser = await User.aggregate([ { $match: { city: city, }, }, { $sample: { size: 1, }, }, { $project: { username: 1, profilepic: 1, }, }, ]); console.log(randomUser[0]?.username) console.log(randomUser[0]?.profilepic) // 确保返回非空数据 res.json(randomUser[0] || {}); } catch (err) { console.log(err); res.status(500).json({ error: err.message }); } });
2. 重构SearchUserPage前端代码
添加状态管理、异步获取当前用户城市、请求后端随机用户数据,并处理加载/错误状态,避免undefined访问:
import { StyleSheet, Text, View, Image, ActivityIndicator, Alert } from 'react-native' import React, { useState, useEffect } from 'react' import AsyncStorage from '@react-native-async-storage/async-storage'; const SearchUserPage = () => { const [randomUser, setRandomUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchRandomUser = async () => { try { // 1. 从AsyncStorage获取当前用户信息 const userDataString = await AsyncStorage.getItem('user'); if (!userDataString) { throw new Error("用户信息不存在,请重新登录"); } const userData = JSON.parse(userDataString); const currentCity = userData.user.city; // 假设userData中已保存city if (!currentCity) { throw new Error("未获取到当前用户城市信息"); } // 2. 请求后端获取同城市随机用户 const response = await fetch(`http://10.0.2.2:3000/user?city=${encodeURIComponent(currentCity)}`); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || "获取随机用户失败"); } const data = await response.json(); setRandomUser(data); } catch (err) { setError(err.message); Alert.alert("错误", err.message); } finally { setLoading(false); } }; fetchRandomUser(); }, []); if (loading) { return ( <View style={styles.container}> <ActivityIndicator size="large" color="#0000ff" /> </View> ); } if (error) { return ( <View style={styles.container}> <Text style={styles.errorText}>{error}</Text> </View> ); } return ( <View style={styles.container}> {randomUser ? ( <View style={styles.userSection}> <View style={styles.imageContainer}> <Image style={styles.image} // 处理头像:如果是网络地址用uri,本地图片用require source={randomUser.profilepic ? { uri: randomUser.profilepic } : require('../path/to/default-avatar.png')} resizeMode="cover" /> </View> <Text style={styles.text}>{randomUser.username || "匿名用户"}</Text> </View> ) : ( <Text style={styles.emptyText}>暂无同城市用户</Text> )} </View> ) } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#f5f5f5', }, userSection: { alignItems: 'center', padding: 20, backgroundColor: 'white', borderRadius: 10, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 5, elevation: 3, }, imageContainer: { width: 120, height: 120, borderRadius: 60, overflow: 'hidden', marginBottom: 15, }, image: { width: '100%', height: '100%', }, text: { fontSize: 18, fontWeight: 'bold', color: '#333', }, errorText: { fontSize: 16, color: '#ff3333', textAlign: 'center', padding: 20, }, emptyText: { fontSize: 16, color: '#666', }, }); export default SearchUserPage
3. 额外优化点
- Mainpage中城市保存逻辑优化:确保userData的结构正确,避免
userdata.user.username出现undefined,可添加空值判断:// 在sendCity函数中添加判断 if (!userdata?.user?.username) { console.error("用户用户名不存在"); return; } - 后端查询容错:在
randomUser[0]访问时添加可选链操作符?.,避免数组为空时报错。
内容的提问来源于stack exchange,提问作者user20952626
相关产品推荐
相关产品推荐

