React中isError为true时未渲染错误页仍提示无法读取userName属性
问题原因
- 首先你代码存在变量名笔误:axios请求的回调参数命名为
userData,但实际取值时用的是userStats,如果实际运行代码也是这个写法,会导致变量未定义报错,建议先统一变量名。 - 核心原因是报错发生在
isError状态更新之前:fetchUser是异步请求,接口回调的执行时机晚于组件首次渲染,首次渲染时isError还是初始的false,此时如果data初始值为undefined(或者你实际代码没有给useState传初始的空数组),直接访问data.userName就会直接抛出错误,哪怕后续请求返回后将isError设为true,也来不及触发重渲染,页面已经崩溃。 - 你没有捕获请求异常:如果接口本身抛出404、跨域等错误,不会进入
.then回调,isError永远不会被设为true,组件会一直尝试读取data.userName触发报错。
修复方案
第一步:调整状态定义,新增加载状态和异常捕获
const [isError, setIsError] = useState<boolean>(false) const [isLoading, setIsLoading] = useState<boolean>(true) // 初始值设为null,避免误访问属性 const [data, setData] = useState<any>(null) const fetchUser = async () => { try { setIsLoading(true) const userData = await axios.get("URL") // 修正变量名统一为userData if (userData.data.items.length === 0) { setIsError(true) console.log("User Doesn't Exist") } else { setIsError(false) setData(userData.data.items[0]) } } catch (err) { // 捕获接口请求异常 setIsError(true) } finally { setIsLoading(false) } }
第二步:调整渲染逻辑的判断优先级
// 优先判断加载态,再判断错误态 if(isLoading) return <div>加载中...</div> if(isError) return <ErrorPage /> // 最后加可选链兜底,避免极端情况data为空报错 return <Success username={data?.userName}/>
内容的提问来源于stack exchange,提问作者niko
相关产品推荐
相关产品推荐

