首页 > 解决方案 > 带有反应路由器的奇怪组件生命周期

问题描述

我有这条路线(简化)

<Route 
  path="/foo/:id">
  render={({match}) => (
    <Page key={match.params.id} id={match.params.id}/>
  )}
</Route>

现在这样做的原因是,当我从/foo/1到时,/foo/2我不想清除和更新现有组件的状态,这对我来说太复杂了。所以我有一个动态密钥,它会导致卸载/foo/1组件并安装一个全新的/foo/2组件。

到目前为止,一切都很好。但这就是问题所在。我观察到的生命周期是这样的

  1. /foo/1重新渲染
  2. /foo/2构造函数
  3. /foo/2组件DidMount
  4. /foo/1组件WillUnmount
  5. /foo/2使成为

为什么在第二个组件安装之前第一个组件不卸载?因此,我得到了奇怪的重新渲染和故障(它连接到 redux 存储并且/foo/2组件的初始化更改了设法重新渲染仍然存在的组件的存储/foo/1)。任何想法如何避免这种情况?

谢谢

标签: reactjsreduxreact-router

解决方案


很难确定您的一小段代码到底发生了什么,但是,我相信您的问题与一些反模式有关;

React 组件构造函数只能用于两件事:

  1. 初始化本地状态
  2. 绑定事件处理程序

https://reactjs.org/docs/react-component.html#constructor

其次,您正在使用render带有内联函数的道具,这意味着当检测到匹配的路由并且父组件重新渲染时,它将重新构建组件,首先卸载它然后再次安装它。为了防止这种情况,您应该在父渲染函数之外定义渲染函数。

第三,因为您有一个动态路由/foo/:id并将值分配给子组件的键,所以反应将其视为不同的组件,并且在当前渲染过程到达阶段:id之前不会卸载它。un-mounting这意味着在很短的时间内您拥有<Page key={1} /><Page key={2}/>存在。

因为这三个问题,你得到了一个看似奇怪的组件生命周期,但实际上它是在按照你告诉它做的事情做出反应。

解决方案:

  1. 将在构造函数中调用的 redux 操作移动<Page />componentDidMount()函数中。
  2. 将内联渲染函数移动到父渲染函数之外。
  3. 卸下key支柱。

推荐阅读