You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React高阶组件渲染无限循环问题:以下代码存在什么错误?

为什么我的React高阶组件ProtectRoute会导致无限循环?

我编写了一个名为ProtectRoute的React高阶组件,代码如下:

export default function ProtectRoute(EnhancedComponent) {
  @connect(state=>state.something,{callAPI})
  class myClass extends Component {
    componentDidMount() {
      this.props.callAPI()
    }
    render() {
      return <EnhancedComponent { ...this.props } />
    }
  }
  return myClass
}

我在路由中这样使用它:

<Route exact path='/app' component={ProtectRoute(App)} />

但出现了无限循环,却无法定位原因,请问这段代码存在什么问题?


这个问题的核心原因是你在Route的component属性里直接调用了ProtectRoute(App),这会触发重复创建组件类,进而导致无限的挂载-卸载循环,具体解释如下:

问题根源

当你写<Route exact path='/app' component={ProtectRoute(App)} />时,每次React渲染这个Route组件,都会执行一次ProtectRoute(App)。而你的ProtectRoute函数内部是直接定义了myClass类,每次调用HOC都会返回一个全新的组件类。

React的diff算法会判断前后两次的component属性是否为同一组件类型:如果是不同的类,React会立即卸载之前的组件实例,重新挂载新的组件实例。新组件挂载时会触发componentDidMount,里面调用的callAPI大概率会触发Redux状态更新,状态更新又会导致路由所在的父组件重新渲染,再次执行ProtectRoute(App)创建新组件——如此往复,就形成了无限循环。

修复方案

解决方法非常直接:把HOC的调用移到路由定义之外,提前创建好包装后的组件,这样每次渲染路由时,component引用的都是同一个组件类:

// 提前定义好受保护的App组件(只执行一次)
const ProtectedApp = ProtectRoute(App);

// 在路由中使用这个预定义的组件
<Route exact path='/app' component={ProtectedApp} />

另外,你也可以优化ProtectRoute本身,把内部的myClass类移到函数外部,避免每次调用HOC都创建新类,但上面的方案已经足够解决当前的无限循环问题。

内容的提问来源于stack exchange,提问作者Thian Kian Phin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:18:00