You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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')错误,需实现展示同城市随机用户的用户名和头像功能并修复该错误。

错误原因分析

  1. SearchUserPage未初始化用户数据:当前页面未获取用户信息或后端返回的随机用户数据,直接访问userData.username导致undefined报错。
  2. 后端GET接口参数获取错误:GET请求无法通过req.body获取参数,后端/user接口用req.body.city会导致city为undefined,进而查询不到用户。
  3. 前端未发起请求获取随机用户: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:15:36