使用GraphQL获取数据时出现TypeError: events.map不是函数问题求助
解决TypeError: events.map is not a function错误
问题场景
使用GraphQL获取数据后,页面渲染时抛出Unhandled Runtime Error TypeError: events.map is not a function错误,相关代码及控制台情况如下:
初始useState代码
const [events, setEvents] = useState < any > ([]);
数据获取函数
const fetchEvents = async () => { const requestBody = { query: ` query{ events{ _id title date price description creator { _id email } } } ` }; setLoading(true); await fetch(`http://localhost:8888/graphql`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }).then(res => { if (res.status !== 200 && res.status !== 201) { throw new Error('Failed!'); } return res.json(); }).then(resData => { const events = resData.data.events; setEvents({ events: events }) }).catch(err => { console.log(err); }) }
渲染代码
{ loading ? events.map((data: any, index: any) => <p key={index}>{data.title}</p> ) : <p>Loading</p> }
控制台日志显示resData.data.events为正常数组结构。
错误原因
- 状态类型篡改:初始
events是数组类型,但setEvents({ events: events })将状态改为了包含events属性的对象,对象没有map方法,调用时直接报错。 - 渲染逻辑颠倒:
loading为true时应显示加载提示,而非直接渲染列表,当前逻辑会在加载状态下尝试调用未正确初始化的events.map。
修复方案
1. 修正状态赋值
将状态赋值改为直接传入数组:
setEvents(events);
2. 修正渲染逻辑
调换loading判断分支:
{ loading ? <p>Loading</p> : events.map((data: any, index: any) => <p key={index}>{data.title}</p> ) }
3. 可选:优化类型定义(推荐)
避免使用any,定义明确的类型接口提升代码健壮性:
interface Creator { _id: string; email: string; } interface Event { _id: string; title: string; date: string; price: number; description: string; creator: Creator; } const [events, setEvents] = useState<Event[]>([]);
完整修正后代码
useState部分
interface Creator { _id: string; email: string; } interface Event { _id: string; title: string; date: string; price: number; description: string; creator: Creator; } const [events, setEvents] = useState<Event[]>([]); const [loading, setLoading] = useState(false); // 假设loading状态已定义
数据获取函数
const fetchEvents = async () => { const requestBody = { query: ` query{ events{ _id title date price description creator { _id email } } } ` }; setLoading(true); try { const res = await fetch(`http://localhost:8888/graphql`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); if (res.status !== 200 && res.status !== 201) { throw new Error('Failed!'); } const resData = await res.json(); setEvents(resData.data.events); } catch (err) { console.log(err); } finally { setLoading(false); // 无论请求成败都关闭加载状态 } }
渲染代码
{ loading ? <p>Loading</p> : events.map((data, index) => <p key={index}>{data.title}</p> ) }
内容的提问来源于stack exchange,提问作者erwin
相关产品推荐
相关产品推荐

