React组件请求后端数据后访问story的title属性提示undefined报错
问题根源
- 响应状态判断逻辑错误:
response.status是数字类型,代码中与字符串'200'做全等判断,所有正常响应都会被误判为错误,触发错误分支的setStoryState({ error: err })操作。这个操作直接全量覆盖了state,初始化时定义的story字段丢失,导致storyState.story变为undefined,访问undefined.title就触发了对应的 TypeError。 - 控制台打印的是对象引用:你在控制台看到的
story对象是请求完成、state更新后的最新值,和组件第一次渲染时的状态并不一致,所以会出现「打印能看到属性但访问报错」的矛盾表现。 - 缺少加载状态判断:组件首次渲染时fetch请求还未返回结果,直接读取属性不符合异步渲染的逻辑。
修复方案
1. 修正状态更新和判断逻辑
- 把状态判断的
'200'改为数字200 - 更新state时使用展开运算符保留原有字段,避免字段丢失
- 补充请求catch分支捕获网络异常
- 修正请求URL中多余的斜杠
2. 渲染时增加状态判断
加载完成前展示加载提示,也可以用可选链?.做兜底容错。
修正后的完整代码:
import { useState, useEffect } from 'react'; import styled from 'styled-components'; export const StoryPage = () => { const [storyState, setStoryState] = useState({ story: {}, isLoaded: false, error: null, }); const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const id = urlParams.get('storyid'); useEffect(() => { fetch('http://localhost:5000/getstory?storyid=' + id) .then((response) => { console.log('response is', response); // 修正:status是数字类型,和数字200比较 if (response.status !== 200) { let err = new Error(); err.message = 'Invalid response code: ' + response.status; // 修正:展开原有state,保留其他字段 setStoryState({ ...storyState, error: err }); } return response.json(); }) .then((json) => { console.log('json is', json); // 修正:展开原有state,保留其他字段 setStoryState({ ...storyState, story: json.story, isLoaded: true, }); }) // 补充:捕获网络异常 .catch(err => { setStoryState({...storyState, error: err}) }); }, []); // 错误状态处理 if (storyState.error) { return <div>请求出错:{storyState.error.message}</div> } // 加载状态处理 if (!storyState.isLoaded) { return <div>加载中...</div> } return ( <> <h1>test</h1> {/* 可选:加可选链做双重兜底 */} <h1>{storyState.story?.title}</h1> </> ); }; export default StoryPage;
内容的提问来源于stack exchange,提问作者cachedcashew
相关产品推荐
相关产品推荐

