React中获取API数据后访问chats数组报TypeError错误求助
解决React访问API数据时的TypeError问题
问题描述
尝试从API地址 http://3.111.128.67/assignment/chat?page=0 获取数据,该API返回包含chats数组的对象。但在React组件中访问data.chats时,抛出错误:Uncaught TypeError: Cannot read properties of null (reading 'chats')。相关代码如下:
import { useEffect, useState } from "react" const url = "http://3.111.128.67/assignment/chat?page=0"; export default function Body() { const [data, setData] = useState(null); const fetchData = async () => { const response = await fetch(url); const jsonData = await response.json(); setData(jsonData); } useEffect(() => { fetchData(); }, []) return ( <div className="mt-40 flex justify-between"> <hr className="border-t-4 w-[35%] mt-2 border-gray-300" /> <div className="text-gray-300">20 May,2023</div> <hr className="border-t-4 w-[35%] mt-2 border-gray-300" /> {/* Chats Area */} {data.chats.map((item) => { return ( <div key={item.id}> <h1>{item.message}</h1> </div> ) })} </div> ) }
问题原因
组件初始化时data的初始值为null,而API请求是异步执行的——组件首次渲染时,fetchData还未完成,data仍为null,此时直接访问data.chats就会触发报错。
解决方案
有三种常见修复方式,任选其一即可:
1. 条件判断渲染
在调用map前先判断data是否存在,确保只有data不为null/undefined时才渲染列表:
{data && data.chats.map((item) => { return ( <div key={item.id}> <h1>{item.message}</h1> </div> ) })}
2. 使用可选链操作符
通过可选链?.简化判断,如果data为null/undefined,表达式会短路返回undefined,避免报错:
{data?.chats.map((item) => { return ( <div key={item.id}> <h1>{item.message}</h1> </div> ) })}
3. 初始化空数组作为默认值
将data的初始值设为包含空chats数组的对象,这样即使未加载完成,data.chats始终是数组,map可以正常执行(遍历空数组,不渲染内容):
const [data, setData] = useState({ chats: [] });
修改后的完整代码示例
以条件判断渲染为例,修改后的代码如下:
import { useEffect, useState } from "react" const url = "http://3.111.128.67/assignment/chat?page=0"; export default function Body() { const [data, setData] = useState(null); const fetchData = async () => { const response = await fetch(url); const jsonData = await response.json(); setData(jsonData); } useEffect(() => { fetchData(); }, []) return ( <div className="mt-40 flex justify-between"> <hr className="border-t-4 w-[35%] mt-2 border-gray-300" /> <div className="text-gray-300">20 May,2023</div> <hr className="border-t-4 w-[35%] mt-2 border-gray-300" /> {/* Chats Area */} {data && data.chats.map((item) => { return ( <div key={item.id}> <h1>{item.message}</h1> </div> ) })} </div> ) }
内容的提问来源于stack exchange,提问作者Gaurav Tak
相关产品推荐
相关产品推荐

