Reacr Router - setState(...): 只能更新一个挂载或挂载的组件

red*_* 87 2 javascript reactjs react-router

我有一个使用 React Router 的应用程序。该应用程序有一些不断更新的组件(它是实时分析数据的仪表板)。使用<Link>链接仪表板的各个部分时,我遇到了以下错误:

warning.js:36 警告:setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了 setState()。这是一个无操作。请检查登录组件的代码。

这是我的代码:

应用程序.js:

<BrowserRouter>
    <Main />    
</BrowserRouter>
Run Code Online (Sandbox Code Playgroud)

主要.js:

<Sidenav />
<Switch>
    <Route exact path='/site-feedback' component={Sitefeedback}/>
    <Route exact path='/logins' component={Logins}/>
    <Route exact path='/shop-sales' component={Shopsales}/>
</Switch>
Run Code Online (Sandbox Code Playgroud)

Sidenav.js:

<Link to='/site-feedback'>Site Feedback</Link>
<Link to="/logins">Logins</Link>
<Link to="/shop-sales">Shop Sales</Link>
Run Code Online (Sandbox Code Playgroud)

如果我<links>只用普通的 a-tags替换它,那么当整个应用程序再次加载时问题就会消失,但我希望不必重新加载我在那里的其他组件,例如 header 或 sidenav。

任何人都知道一个好的解决方法吗?我无法想象我是唯一一个在 React Router 上遇到过这个问题的人......

谢谢

Dmi*_*nko 5

您的组件之一设置间隔或订阅外部事件的可能性很大。您需要取消订阅所有事件并清除 中的所有超时/间隔componentWillUnmount,它应该如下所示:

class SomeComponent extends Component {
  componentDidMount() {
    this.timeoutId = setInterval(...)
    subscribeToSomeEvent(...)
  }
  componentWillUnmount() {
    clearInterval(this.timeoutId)
    unsubscribeFromSomeEvent(...)
  }
}
Run Code Online (Sandbox Code Playgroud)

您可能会收到该消息的另一个原因是当用户更改页面(并因此卸载当前组件)而某些 ajax 请求正在进行时,一旦请求完成,它会尝试更新卸载的组件。您可以设置一些标志来避免那些延迟更新:

class SomeComponent extends Component {
  componentDidMount() {
    fetch(...).then(data => {
      if (this.unmounted) return
      // process the data
    })
  }
  componentWillUnmount() {
    this.unmounted = true
  }
}
Run Code Online (Sandbox Code Playgroud)