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

NextJS中无法获取嵌套对象问题求助

问题原因

组件首次渲染时,useUserData返回的初始值是null,此时直接访问user.profile就会触发Cannot read properties of null (reading 'profile')错误。你看到console.log(user)有值,是因为API请求完成后组件重新渲染,React会更新控制台里的对象引用,但首次渲染的错误已经发生了。

解决方法

1. 使用可选链操作符(推荐)

直接在访问属性时添加?.,当user为null/undefined时会安全返回undefined,不会报错:

const ViewProfile = () => {
    const router = useRouter();

    const user = useUserData();
    console.log(user);

    // 用可选链替代直接访问
    const data = user?.profile;
    console.log(data);

    // 剩余代码
}

2. 条件判断后再访问

在访问profile前先检查user是否存在:

const ViewProfile = () => {
    const router = useRouter();

    const user = useUserData();
    console.log(user);

    let data;
    if (user) {
        data = user.profile;
        console.log(data);
    }

    // 剩余代码
}

3. 修改钩子的初始状态

把useUserData里的初始状态从null改为空对象{},避免首次渲染时出现null:

// useUserData.js
const useUserData = () => {
    const userToken = Cookies.get("sessionToken");
    // 初始值改为空对象
    const [userData, setUserData] = useState({});

    // 剩余代码不变
};

注意:这种方式需要后续判断user.profile是否存在,因为初始空对象的profile是undefined。

4. 添加加载状态(更友好的用户体验)

在钩子中增加加载状态,组件里先显示加载提示,等数据返回后再渲染内容:

// useUserData.js
const useUserData = () => {
    const userToken = Cookies.get("sessionToken");
    const [userData, setUserData] = useState(null);
    // 新增加载状态
    const [isLoading, setIsLoading] = useState(true);

    useEffect(() => {
        async function fetchData() {
            try {
                setIsLoading(true);
                const res = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URI}/user/profile`,{
                    method: "GET",
                    headers: {
                        "Content-Type": "application/json",
                        "Authorization": `Bearer ${userToken}`,
                    },
                });

                const data = await res.json();
                if (res.ok) {
                    setUserData(data);
                }
            } catch (err) {
                console.error(err);
            } finally {
                setIsLoading(false);
            }
        }
    
        if (userToken) {
            fetchData();
        } else {
            setIsLoading(false);
        }

    }, [userToken]);

    return { userData, isLoading };
};

然后在组件中使用:

const ViewProfile = () => {
    const router = useRouter();

    const { userData: user, isLoading } = useUserData();

    if (isLoading) {
        return <div>加载中...</div>;
    }

    // 此时user已确保有值(或API请求失败后仍为null,可再加判断)
    const data = user?.profile;
    console.log(data);

    // 剩余代码
}

内容的提问来源于stack exchange,提问作者SUBS2905

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:53:11