React中如何根据API返回结果控制Popup弹窗的显示
问题根因
- 你将axios请求直接放在了渲染阶段执行的
createPopup函数中,每次setState更新showPopup都会触发组件重新渲染,重渲染又会重新调用createPopup、发起新的请求、再次触发setState,就形成了死循环。 - axios是异步请求,请求发出去后不会阻塞后续代码执行,所以第一次渲染时拿到的永远是
showPopup的初始值false,要等请求响应回来setState执行完成,第二次渲染才能拿到更新后的值。
修复方案
1. 把API请求移到副作用逻辑中执行
不要在渲染函数里发请求,把请求逻辑放到类组件的componentDidMount/componentDidUpdate生命周期(函数组件对应useEffect)里,只在依赖的myUser.id变化时才重新发起请求,避免重复触发:
// 类组件示例 componentDidMount() { this.fetchPopupData() } componentDidUpdate(prevProps) { // 仅用户ID变化时才重新请求数据 if (prevProps.myUser.id !== this.props.myUser.id) { this.fetchPopupData() } } fetchPopupData = () => { const { myUser } = this.props MyAxiosCall.fetchGetArray(myUser.id) .then((data) => { // 简化判断逻辑,直接赋值布尔值 this.setState({ showPopup: data.length < 1 }) }) }
2. 简化createPopup渲染逻辑
渲染函数只做根据当前状态返回对应UI的事,不要包含请求逻辑:
createPopup = () => { const { showPopup } = this.state return showPopup ? <Popup /> : null }
如果需要等待请求返回前不展示任何内容,可以额外加加载状态:
- 给state新增初始值
isLoading: true - 请求的
then和catch回调里都把isLoading设为false - 渲染时先判断加载状态,返回占位内容或者
null即可:
createPopup = () => { const { showPopup, isLoading } = this.state if (isLoading) return null return showPopup ? <Popup /> : null }
内容的提问来源于stack exchange,提问作者Frodo
相关产品推荐
相关产品推荐

