React.js中useEffect内使用异步函数的渲染异常问题
React异步数据渲染时的TypeError问题解决
问题根源
你当前的判断data? data[0][0].stat.avg : ""无效,因为初始状态data是空数组[],空数组属于JavaScript中的真值,所以条件分支会直接执行data[0][0].stat.avg。但此时数组为空,data[0]是undefined,继续访问[0]就会抛出TypeError。
解决方案
方案1:使用可选链操作符(最简洁)
用可选链?.逐层检查每一级是否存在,只要某一级不存在就返回undefined,再配合空值合并运算符??设置默认值:
import React, { useState, useEffect } from "react"; import "./App.css"; import customAsyncFunction from "./Functions"; function App() { const [data, setData] = useState([]); const fetchInfo = () => { customAsyncFunction().then((d) => { setData(d); }); }; useEffect(() => { fetchInfo(); }, []); return <div>{data?.[0]?.[0]?.stat?.avg ?? ""}</div>; }
方案2:修改初始状态为null/undefined
把初始data设为null,这样data?的判断会正确识别未加载状态:
import React, { useState, useEffect } from "react"; import "./App.css"; import customAsyncFunction from "./Functions"; function App() { const [data, setData] = useState(null); // 修改初始值为null const fetchInfo = () => { customAsyncFunction().then((d) => { setData(d); }); }; useEffect(() => { fetchInfo(); }, []); return <div>{data ? data[0][0].stat.avg : ""}</div>; }
方案3:添加加载状态(用户体验更友好)
新增loading状态,在数据未加载完成时显示加载提示:
import React, { useState, useEffect } from "react"; import "./App.css"; import customAsyncFunction from "./Functions"; function App() { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); const fetchInfo = () => { customAsyncFunction() .then((d) => { setData(d); }) .finally(() => { setLoading(false); }); }; useEffect(() => { fetchInfo(); }, []); if (loading) { return <div>加载中...</div>; } return <div>{data?.[0]?.[0]?.stat?.avg ?? ""}</div>; }
额外说明
你提到重新加载页面后注释再取消注释能正常渲染,是因为此时customAsyncFunction的请求可能有缓存,数据会同步返回,data被立即更新,避免了首次渲染时的空数组访问问题。但这种依赖缓存的方式不可靠,必须通过严谨的空值检查或状态管理来解决根本问题。
内容的提问来源于stack exchange,提问作者bwiss11
相关产品推荐
相关产品推荐

