React+Apollo Client获取GraphQL嵌套数组数据遇undefined问题求助
React + Apollo Client 访问嵌套GraphQL数组返回undefined问题
我用React结合Apollo Client从GraphQL获取数据,目前能获取到数组的第一层数据,但尝试访问嵌套数组时却得到undefined,希望解决这个问题。
相关数据结构截图
- 分类名称结构:

- 返回的数据结构:

- 控制台输出:

当前代码
import {useState, useEffect,useMemo} from 'react'; import { gql, useQuery } from '@apollo/client'; import {GET_CLOTHES} from "./GetClothes.js" import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'; import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'; function Clothes() { const { loading, error, data } = useQuery(GET_CLOTHES); const [products,setProducts] = useState([]); const [index,setIndex] = useState(0); useEffect(() => { if (data) { setProducts(data.categories.products); console.dir(data.categories.products); } },[data]); //console.dir(products); /* useEffect(() => { if(!loading && data){ setProducts(data); } }, [loading, data]) */ if (loading) return 'Loading...' if (error) return `Error! ${error.message}` return <div> { // Products is actually products products?.map((product,index) => { if (product.name === 'clothes') { //filter // Iterate through products.products to obtain the product data. const {name,brand,description,gallery,category} = product; return <p>{name}</p> }}) } </div> } export default Clothes;
问题原因及解决方法
核心问题
从控制台截图能看到,data.categories是数组类型,你现在直接写data.categories.products,相当于给数组对象取products属性,自然返回undefined。
修复方案
方案1:前端过滤处理
修改useEffect里的逻辑,先找到目标分类再取嵌套的products:
useEffect(() => { if (data) { // 从categories数组中找到name为clothes的分类项 const clothesCategory = data.categories.find(item => item.name === 'clothes'); if (clothesCategory) { // 取出该分类下的products数组 setProducts(clothesCategory.products); } } }, [data]);
同时返回部分的代码可以简化(已经拿到目标products,无需再过滤):
return <div> {products?.map((product, idx) => { const {name, brand, description, gallery, category} = product; // 注意给列表项加唯一key return <p key={idx}>{name}</p>; })} </div>
方案2:GraphQL查询时直接过滤(更高效)
修改GET_CLOTHES的查询语句,直接在后端过滤出name为clothes的分类,减少前端处理逻辑:
query GetClothes { categories(where: {name: "clothes"}) { name products { name brand description gallery category } } }
此时前端useEffect可以简化为:
useEffect(() => { if (data && data.categories.length > 0) { setProducts(data.categories[0].products); } }, [data]);
内容的提问来源于stack exchange,提问作者KubraG
相关产品推荐
相关产品推荐

