已做空值判断仍出现Cannot read property 'length' of null错误求助
问题:React组件渲染时出现“Cannot read property 'length' of null”错误
我有一个从数据库获取数据的React组件,获取过程中显示加载动画,数据请求逻辑在useEffect中实现:
useEffect(() => { axios.post("/api/fetch/fetchEducation", { id: props.id }) .then((response) => { console.log(response) setEducation(response.data) }) .then(() => { setLoading(false) }) .catch(() => { setLoading(false) }) }, [props.id])
组件声明了数组类型的状态:
const [education, setEducation] = useState([])
在return部分我想实现以下逻辑:
- 当
loading为true时显示加载动画 - 当
loading为false且education为null或长度为0时,显示空面板 - 当
loading为false且education不为null且长度大于0时,渲染数据列表
当前接口在无数据时返回null,我写的渲染代码如下:
<div className="dashboard-parent"> <div className="dashboard"> { loading === true ? <DashboardPending /> : null } { (education == null || education.length === 0) && loading === false ? <EmptyDashboard content="No education added." /> : null } { ( education != null || education.length > 0) && loading === false ? <> { education.map((edu, index) => { return ( <DashboardListItem first={edu.Course} second={edu.Institution} third={edu.StartDate} fourth={edu.EndDate} key={index} /> ) })} </> : null } </div> </div>
但运行时出现了“Cannot read property 'length' of null”错误,请问问题出在哪里?
解决方案
错误原因
当接口返回null时,education会被设置为null,此时你的判断条件里直接调用education.length就会报错——null没有length属性。
具体有两个核心问题:
- 第三个判断条件用了
||(逻辑或),这意味着只要其中一个条件为true就会进入分支。当education为null时,education != null是false,代码会继续判断education.length > 0,直接触发报错。 - 这个判断逻辑本身不符合需求:你需要的是同时满足
education不为null且长度大于0,应该用&&(逻辑与)而非||。
修正后的渲染代码
<div className="dashboard-parent"> <div className="dashboard"> {loading === true && <DashboardPending />} {loading === false && ( <> {(education == null || education.length === 0) && <EmptyDashboard content="No education added." />} {education != null && education.length > 0 && ( <> {education.map((edu, index) => ( <DashboardListItem first={edu.Course} second={edu.Institution} third={edu.StartDate} fourth={edu.EndDate} key={index} /> ))} </> )} </> )} </div> </div>
额外优化建议
你可以在数据请求环节直接把null转为空数组,后续渲染时就不用再处理null的情况,逻辑更简洁:
useEffect(() => { axios.post("/api/fetch/fetchEducation", { id: props.id }) .then((response) => { // 用空值合并运算符把null转为空数组 setEducation(response.data ?? []) }) .then(() => setLoading(false)) .catch(() => setLoading(false)) }, [props.id])
简化后的渲染代码:
<div className="dashboard-parent"> <div className="dashboard"> {loading === true && <DashboardPending />} {loading === false && ( <> {education.length === 0 && <EmptyDashboard content="No education added." />} {education.length > 0 && ( <> {education.map((edu, index) => ( <DashboardListItem first={edu.Course} second={edu.Institution} third={edu.StartDate} fourth={edu.EndDate} key={index} /> ))} </> )} </> )} </div> </div>
内容的提问来源于stack exchange,提问作者Jon Nicholson
相关产品推荐
相关产品推荐

