useEffect获取API数据控制台可见但报读取undefined属性错误
报错核心原因
- 组件return语句外定义
test变量的map逻辑没有任何空值防护,组件每次渲染都会直接执行。虽然初始tweets是空数组时map不会进入回调,但只要接口返回的entries数组里混入不符合结构的条目,这里会第一时间抛错。 - 第三方类推特timeline接口返回的entries数组不是纯推文内容,会混入翻页游标、分割线、广告、置顶提示等特殊条目,这类条目完全没有
content.itemContent.tweet_results的嵌套路径,不加判断直接读属性必然触发类型错误。 - 控制台看到log有数据是浏览器的对象懒解析机制导致的:你在控制台打印对象时,显示的是手动点击展开对象那一刻的最终值,不是代码执行到log那一行的瞬时值,不能作为打印当下属性路径完全存在的依据。
- 你写的渲染判断只校验了
tweets数组本身是否存在、是否有长度,没有校验数组每一项内部的深层嵌套属性是否存在,只要有一条数据缺了路径上的任意属性,整个组件渲染就会崩溃,页面自然无法显示任何内容。
修复方案
- 先删掉return外层那个无意义的
test变量map逻辑,这是触发报错的直接原因之一,没有实际作用还无任何防护。 - 接口取值、数据遍历访问深层属性时全链路加可选链防护,提前过滤掉结构不符合要求的无效条目,不要硬编码instructions的索引,避免接口返回顺序变动时拿错数据。
- 渲染列表时补上唯一key属性,避免渲染更新异常。
修复后的可运行代码:
const LatestTweets = () => { const [tweets, setTweets] = useState([]); useEffect(() => { const getTweets = async () => { try { const response = await axios.get("https://myendpoint.com"); const timelineInstructions = response?.data?.data?.user?.result?.timeline?.timeline?.instructions || []; // 匹配正确的指令项,不要硬编码索引[1] const addEntriesInstruction = timelineInstructions.find(item => item?.type === "TimelineAddEntries"); const allEntries = addEntriesInstruction?.entries || []; // 过滤掉非推文的无效条目 const validTweets = allEntries.filter(entry => { return entry?.content?.itemContent?.tweet_results?.result?.legacy?.full_text; }); setTweets(validTweets); } catch (err) { console.log(err); } }; getTweets(); }, []); return ( <div> {tweets.map((t) => ( <p key={t.entryId}> {t.content.itemContent.tweet_results.result.legacy.full_text} </p> ))} </div> ); };
补充说明:如果后续需要兼容转推、引用推文的场景,还要额外判断
tweet_results下的结构是否是转推类型,对应取retweeted_status_result路径下的内容即可。
内容的提问来源于stack exchange,提问作者Waterfall
相关产品推荐
相关产品推荐

