React中如何用map渲染GraphQL获取的订阅者姓名与邮箱?
React + GraphQL 渲染订阅者数据问题解决
问题描述
我刚开始学习React,用GraphQL获取订阅者数据时,console.log能正常看到数据,但用map遍历数组获取内容时返回undefined,想知道怎么正确用map渲染每个订阅者的name和email。
相关代码
import React, { useState } from "react"; import { gql, useQuery } from "@apollo/client"; const GET_SUBSCRIBERS_QUERY = gql` query { subscribers(stage: DRAFT) { name email id } } `; const App = () => { const { data } = useQuery(GET_SUBSCRIBERS_QUERY); return ( <> <h1>@fsouza/table-data</h1> <table> <thead> <tr> <th>Name</th> <th>Email</th> </tr> </thead> <tbody> {data.subscribers.map((subscriber) => ( <tr key={subscriber.id}> <td>{subscriber.name}</td> <td>{subscriber.email}</td> </tr> ))} </tbody> </table> </> ); }; export default App;
问题原因
useQuery是异步请求,组件首次渲染时GraphQL请求还未完成,此时data为undefined,直接访问data.subscribers会触发“无法读取undefined的subscribers属性”的错误,导致map无法执行。
解决方法
方法1:可选链+空数组兜底(最简洁)
给data添加可选链操作符?.,确保只有data存在时才访问subscribers,同时用|| []兜底,保证即使subscribers为空也能返回空数组,避免map报错:
{data?.subscribers?.map((subscriber) => ( <tr key={subscriber.id}> <td>{subscriber.name}</td> <td>{subscriber.email}</td> </tr> )) || []}
方法2:利用loading状态处理加载过程
useQuery会返回loading状态,可在加载时显示提示,完成后再渲染数据,提升用户体验:
const App = () => { const { data, loading, error } = useQuery(GET_SUBSCRIBERS_QUERY); if (loading) return <div>加载中...</div>; if (error) return <div>请求出错:{error.message}</div>; return ( <> <h1>@fsouza/table-data</h1> <table> <thead> <tr> <th>Name</th> <th>Email</th> </tr> </thead> <tbody> {data.subscribers.map((subscriber) => ( <tr key={subscriber.id}> <td>{subscriber.name}</td> <td>{subscriber.email}</td> </tr> ))} </tbody> </table> </> ); };
方法3:给data设置默认解构值
解构data时直接设置默认值,确保subscribers始终是数组:
const { data = { subscribers: [] } } = useQuery(GET_SUBSCRIBERS_QUERY);
这样即使data初始为undefined,也能通过默认值拿到空数组,map可正常执行。
内容的提问来源于stack exchange,提问作者Andreia Souza
相关产品推荐
相关产品推荐

