为什么React中setDetails初始为空后才出现接口返回的对应数据?
问题原因解析
这个是React组件渲染流程 + 异步网络请求的固有特性导致的,属于正常现象,具体逻辑如下:
- 组件首次执行渲染时,会先运行函数体内的同步代码,
useState({})会将details的初始值设置为空对象,这个时候接口请求还未触发,首次渲染用到的details就是这个初始空值,你写在return里的console.log(details)第一次会输出空对象。 - 你用来触发接口请求的
useEffect,执行时机是组件首次渲染完成并挂载到DOM之后,所以首次渲染阶段不会运行getDetails方法。 fetch发起的是异步网络请求,不会阻塞JS主线程执行,需要等服务器返回响应、拿到接口数据后,才会执行setDetails(data)。而setDetails会触发组件重新渲染,第二次渲染时details才会被赋值为接口返回的完整数据,控制台也会第二次打印出拿到的接口数据。
现有代码优化建议
你当前的代码在首次渲染时,details.backdrop_path为undefined,拼接后的img地址会出现异常,建议做兼容处理:
- 提前加加载态判断,避免渲染异常内容:
const SingleTvShow = () => { const { id } = useParams(); const [details, setDetails] = useState({}); const { imgUrl } = useGlobalContext(); // 省略其余逻辑... // 数据未加载完成时返回加载占位 if (!Object.keys(details).length) return <div>数据加载中...</div> return ( <div> <img src={imgUrl + details.backdrop_path} alt="show" /> </div> ); };
- 或者对图片地址做兜底处理,避免出现无效地址:
<img src={details.backdrop_path ? `${imgUrl}${details.backdrop_path}` : '/default-placeholder.png'} alt="show" />
内容的提问来源于stack exchange,提问作者user16213746
相关产品推荐
相关产品推荐

