useQuery初始返回undefined致报错,如何修复应用崩溃问题?
修复useQuery初始数据undefined导致的应用崩溃问题
问题根源
useQuery是异步发起GraphQL请求的,组件首次渲染时请求还未完成,此时data为undefined,直接访问data.products会触发"can not read properties of undefined"错误,导致应用崩溃。
修复方案
方案1:使用可选链+空值合并运算符
在访问嵌套属性时用?.避免访问undefined的属性,同时用??给数组设置默认空数组,确保map方法能正常执行:
const RenderProducts = () => { const { data } = useQuery(GET_PRODUCTS); // 修复console.log的报错问题 console.log(data?.products?.map(product => product) ?? []); // 给products设置默认空数组,保证map可执行 const products = (data?.products ?? []).map((product) => { return ( <li className="productList__item" key={product.id}> {/* 列表项必须加唯一key,避免React警告 */} <img className="productList__item-img" src={product.mainImage?.url} alt={product.title} /> {/* 若mainImage可能为undefined,同样用可选链 */} <div className="productList__item-descr"> <div className="productList__item-title">{product.title}</div> <div className="productList__item-price">{product.price} $</div> </div> </li> ) }) return <ul>{products}</ul> }
方案2:利用useQuery的loading状态做加载判断
useQuery会返回loading状态,请求未完成时loading为true,此时可以显示加载占位内容,避免渲染未准备好的数据:
const RenderProducts = () => { const { data, loading, error } = useQuery(GET_PRODUCTS); // 请求加载中时显示占位 if (loading) return <div>加载中...</div>; // 请求出错时显示错误提示 if (error) return <div>加载失败:{error.message}</div>; // 此时data已确保存在,可安全访问 console.log(data.products.map(product => product)); const products = data.products.map((product) => { return ( <li className="productList__item" key={product.id}> <img className="productList__item-img" src={product.mainImage.url} alt={product.title} /> <div className="productList__item-descr"> <div className="productList__item-title">{product.title}</div> <div className="productList__item-price">{product.price} $</div> </div> </li> ) }) return <ul>{products}</ul> }
方案3:条件判断data是否存在后再渲染
直接判断data是否有效,只有当data存在时才渲染产品列表:
const RenderProducts = () => { const { data } = useQuery(GET_PRODUCTS); // data未就绪时返回null或加载占位 if (!data) return null; console.log(data.products.map(product => product)); const products = data.products.map((product) => { return ( <li className="productList__item" key={product.id}> <img className="productList__item-img" src={product.mainImage.url} alt={product.title} /> <div className="productList__item-descr"> <div className="productList__item-title">{product.title}</div> <div className="productList__item-price">{product.price} $</div> </div> </li> ) }) return <ul>{products}</ul> }
额外提示
- React列表渲染必须给每个列表项添加唯一
key属性,建议使用产品的唯一标识(如product.id),避免触发React警告。 - 若
product.mainImage也可能为undefined,同样可以用product.mainImage?.url的方式防止报错。
内容的提问来源于stack exchange,提问作者shiroSn
相关产品推荐
相关产品推荐

