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

React Hooks/Context编译渲染报错:无法读取videos属性

问题原因分析

这个错误的核心是异步数据加载的渲染时机问题:

  • 组件初始化时,text的状态是{}空对象;useEffect中的fetch是异步操作,第一次渲染时还没完成数据请求,无法拿到JSON内容。
  • 此时text[language](比如默认的text['ES'])返回undefined,继续访问.videos就会触发Cannot read properties of undefined (reading 'videos')错误。
  • 编译后修改代码触发热重载时,JSON数据已经被缓存,组件能直接拿到数据,所以不会报错。

解决方案

方案1:初始化默认语言数据

在useState里给text设置与JSON结构匹配的初始值,确保第一次渲染时有可用数据:

const [text, setText] = useState({
  ES: {
    videos: "Vídeos",
    photos: "Fotos",
    cv: "CV",
    press: "Prensa",
    contact: "Contacto"
  },
  EU: {
    videos: "Bideoak",
    photos: "Argazkiak",
    cv: "CV",
    press: "Prentsa",
    contact: "Kontaktua"
  },
  EN: {
    videos: "Videos",
    photos: "Photos",
    cv: "CV",
    press: "Press",
    contact: "Contact"
  }
});

方案2:使用可选链做空值保护

在访问嵌套属性前,用可选链操作符?.判断上层属性是否存在,避免报错:

<li><Link to="/videos" className="nav-item">{text[language]?.videos}</Link></li>
<li><Link to="/photos" className="nav-item">{text[language]?.photos}</Link></li>
<li><Link to="/cv" className="nav-item">{text[language]?.cv}</Link></li>
<li><Link to="/press" className="nav-item">{text[language]?.press}</Link></li>
<li><Link to="/contact" className="nav-item">{text[language]?.contact}</Link></li>

也可以加上加载提示:

<li><Link to="/videos" className="nav-item">{text[language]?.videos || '加载中...'}</Link></li>

方案3:添加加载状态控制渲染

在Context中新增加载状态,确保数据加载完成后再渲染子组件:
修改LanguageContext.js:

import { createContext, useContext, useState, useEffect } from "react";

const LanguageContext = createContext(undefined)

export const LanguageProvider = ({ children }) => {
    const [language, setLanguage] = useState('ES');
    const [text, setText] = useState({});
    const [isLoading, setIsLoading] = useState(true); // 新增加载状态

    const updateLanguage = e => setLanguage(e.target.value)

    useEffect(() => { 
        fetch(`https://raw.githubusercontent.com/julenclarke/ejtos-react_budget_app/main/languagesdata.json`) 
          .then((response) => response.json()) 
          .then((jsonData) => {
              setText(jsonData);
              setIsLoading(false);
          })
          .catch((error) => {
              console.log(error);
              setIsLoading(false);
          }); 
      }, []); 

    return (
        <LanguageContext.Provider
            value={{
                language,
                updateLanguage,
                text
            }}
        >
            {isLoading ? <div>加载中...</div> : children}
        </LanguageContext.Provider>
    )
}

export const useLanguage = () => useContext(LanguageContext);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 08:17:35