如何在React组件中调用JSON数据?渲染时报类型错误求助
一步步排查并修复你的日程渲染错误
让我帮你拆解下问题所在,然后给出具体的修复方案:
错误根源分析
你遇到的TypeError: Cannot convert undefined or null to object,主要是两个问题叠加导致的:
- 组件初始化时的空状态没有处理,导致访问
undefined的属性时出错 - 数组遍历的方法用错了——你把数组当成对象来处理了
具体修复步骤
1. 修正组件传参与状态接收逻辑
在App.js里,你把items[0](单个的日程对象,包含id、day、events数组)赋值给了timeTableData,但在Component.js里却解构了props.items——这明显不匹配,因为你传的是单个对象,不是带items属性的对象。
首先修改App.js里的组件调用:
// App.js中渲染Component的部分 <Component timetable={timeTableData} />
然后在Component.js里正确接收这个属性:
const { timetable } = props;
2. 处理异步加载的空状态
因为useEffect是异步执行的,组件第一次渲染时timeTableData是你设置的初始值[](空数组),这时候timetable.events根本不存在,直接调用Object.keys就会触发报错。我们需要先做存在性判断:
// Component.js里 if (!timetable?.events) { return <p>加载中...或者暂无数据</p>; }
3. 修正数组遍历的方式
你的events是数组,不是对象,用Object.keys(items.events)会返回数组的索引字符串(比如"0"、"1"),而你需要的是数组里的每个事件对象。直接用数组原生的map方法遍历就好:
const listGroupItems = timetable.events.map((eventItem) => { return ( <CardBody key={eventItem.key}> {eventItem.start} {eventItem.end} {eventItem.event} </CardBody> ) })
可选优化:调整初始状态
把App.js里的初始状态从[]改成null,更符合数据的实际结构,避免混淆:
const [timeTableData, setTimeTableData] = useState(null)
完整修复后的代码示例
App.js
import { useState, useEffect } from 'react'; import axios from 'axios'; import Component from './Component'; function App() { const [timeTableData, setTimeTableData] = useState(null) useEffect(() => { const fetchData = async () => { const tTableResult = await axios('./timetable.json') setTimeTableData(tTableResult.data.items[0]) } fetchData() }, []) return ( <div className="App"> {/* 加载状态提示 */} {timeTableData ? <Component timetable={timeTableData} /> : <p>加载日程中...</p>} </div> ); } export default App;
Component.js
import { CardBody } from '你的卡片组件库'; // 替换成实际使用的组件库 const Component = (props) => { const { timetable } = props; // 处理空/未加载状态 if (!timetable?.events) { return <p>暂无日程数据</p>; } const listGroupItems = timetable.events.map((eventItem) => { return ( <CardBody key={eventItem.key}> {eventItem.start} - {eventItem.end}: {eventItem.event} </CardBody> ); }); return <div>{listGroupItems}</div>; }; export default Component;
这样就能正确渲染所有日程事件,解决你遇到的错误了。
内容的提问来源于stack exchange,提问作者Onur Şahal
相关产品推荐
相关产品推荐

