React中已设置初始值的state仍然出现undefined该如何解决
问题根因
- 你没有处理
useQuery的错误返回场景:当请求出错时loading会变为false但data是undefined,你的useEffect会直接把undefined赋值给product状态,导致后续渲染时product为空。 - 额外的状态同步冗余:你不需要把
useQuery返回的data单独存入本地state,useQuery会自动管理返回数据的更新,多一层状态同步反而容易出现时序不同步的问题:当loading结束进入渲染阶段时,useEffect还未执行,状态还未更新,虽然后续会触发重渲染,但如果数据结构不匹配很容易出现偶发报错。 - 缺少值为空的防御判断:不管是父组件传值还是子组件取值,都没有做空值兼容,执行
map操作前没有判断目标数组是否存在。
修复方案
方案1:移除冗余的本地state(最推荐)
直接使用useQuery返回的data,不需要单独存state,同时补充错误处理和空值兼容:
import React, { useEffect, useState } from 'react'; import './App.css'; import { useQuery, gql } from "@apollo/client"; import { LOAD_PRODUCT } from "./GraphQL/Queries"; import Product from './Components/Product'; function App() { const { error, loading, data } = useQuery(LOAD_PRODUCT) if(loading) return <h1>Loading...</h1> // 补充错误处理 if(error) return <h1>加载商品数据失败</h1> return ( <> {/* 直接传useQuery返回的data,不需要额外存state */} <Product product={data}/> </> ); } export default App;
方案2:保留state的话补充空值判断
如果你确实需要把数据存在本地state,修改useEffect的逻辑,避免把undefined赋值给product:
useEffect(() => { // 只有data有值的时候才更新状态 if(data) setProduct(data) }, [data])
方案3:子组件补充防御性判断
在Product组件中执行map操作的地方使用可选链或者空值兜底,比如:
// 原来的写法 product.someList.map(item => <div key={item.id}>{item.name}</div>) // 修改为 product?.someList?.map(item => <div key={item.id}>{item.name}</div>) ?? [] // 或者先判断再渲染 {product?.someList && product.someList.map(item => <div key={item.id}>{item.name}</div>)}
内容的提问来源于stack exchange,提问作者pokelkrique
相关产品推荐
相关产品推荐

