React中Axios GET请求首次返回undefined及多次打印日志问题
问题解答
1. 为什么首次获取的detail是undefined?
这不是接口返回了undefined,是代码执行顺序的问题:
- React组件首次渲染时,会优先执行所有同步代码,你写在组件顶层的
console.log(Hi ${detail})会在请求发起前就执行,此时detail还是你初始化useState('')的空值,请求还没返回结果。 useEffect里的异步请求是在组件挂载完成后才发起的,async/await只是保证你在请求返回后再执行setDetail,不会阻塞组件的首次渲染流程。等请求成功调用setDetail后,触发组件重新渲染,你才能拿到正确的detail值。
如果确认接口实际返回的是undefined,可以在await axios之后加一行console.log(res)检查接口实际返回的内容,绝大多数情况是打印时机早于请求完成时间导致的误解。
2. 为什么控制台会多次打印日志?
多次打印是以下几个原因共同导致的:
- 组件首次渲染打印1次
- 请求完成调用
setDetail触发组件重渲染,打印1次 - 如果你开启了React开发环境的严格模式(根组件被
<React.StrictMode>包裹),组件会被强制挂载2次,useEffect会执行2次,会发起2次请求,对应的渲染和打印次数也会翻倍 - 你当前
useEffect的依赖项是id,如果id发生变化,会再次触发请求和重渲染,也会新增打印记录
额外优化建议
- 你在请求头里加的
Access-Control-Allow-Origin是无效的,这个是跨域响应头,需要后端配置返回,前端添加没有作用 - 你当前请求URL是写死的
/1,没有用到id状态,useEffect的依赖项id没有实际意义,如果需要根据id请求不同数据,把URL改为http://127.0.0.1:8000/api/recipe-detail/${id}即可 - 建议给axios请求加
try/catch捕获错误,避免接口报错导致页面崩溃 - 渲染依赖
detail的内容时可以加加载判断,比如detail ? <div>{detail.title}</div> : <div>加载中...</div>,避免空值报错
内容的提问来源于stack exchange,提问作者user14653534
相关产品推荐
相关产品推荐

