为啥 componentDidMount 在 react.js 和 redux 中被多次调用?

Posted

技术标签:

【中文标题】为啥 componentDidMount 在 react.js 和 redux 中被多次调用?【英文标题】:Why componentDidMount gets called multiple times in react.js & redux?为什么 componentDidMount 在 react.js 和 redux 中被多次调用? 【发布时间】:2017-02-19 19:34:39 【问题描述】:

我读到 componentDidMount 在初始渲染中只被调用一次,但我看到它被多次渲染。

看来我创建了一个递归循环。

componentDidMount 调度操作以获取数据 在接收到数据后,它会触发成功操作以将数据存储在 redux 状态。 父 React 组件已连接到 redux 存储,并且在上述步骤中刚刚更改的条目具有 mapStateToProps 父组件渲染子组件(通过变量以编程方式选择) 子组件的 componentDidMount 再次被调用 它调度操作以获取数据

我认为这就是正在发生的事情。我可能错了。

如何停止循环?

这是以编程方式呈现子组件的代码。

 function renderSubviews(viewConfigs, viewConfig, getSubviewData) 

   return viewConfig.subviewConfigs.map((subviewConfig, index) => 
     let Subview = viewConfigRegistry[subviewConfig.constructor.configName]
     let subviewData = getSubviewData(subviewConfig)

     const key = shortid.generate()
     const subviewLayout = Object.assign(, subviewConfig.layout, key: key)
     return (
       <div
         key=key
         data-grid=subviewLayout
         >
         <Subview
           ...subviewData
           />
       </div>
     )
   )
 

【问题讨论】:

【参考方案1】:

一个组件实例只会被挂载一次,当它被删除时会被卸载。在您的情况下,它会被删除并重新创建。

key 属性的重点是帮助 React 找到相同组件的先前版本。这样它就可以用新的道具更新以前的组件,而不是创建一个新的。

React 通常可以在没有键的情况下正常工作,但包含项目的列表除外。它需要一个密钥,以便在重新排列、创建或删除项目时进行跟踪。

在您的情况下,您明确告诉 React 您的组件与前一个不同。您在每次渲染时都提供了一个新键。这会强制 React 将前一个实例视为已被删除。该组件的所有子组件也会被卸载和拆除。

您应该做的不是(永远)随机生成密钥。键应始终基于组件正在显示的数据的标识。如果它不是列表项,您可能不需要密钥。如果是列表项,最好使用从数据身份派生的键,例如 ID 属性,或者可能是多个字段的组合。

如果生成随机密钥是正确的做法,React 会为您处理好。

您应该将初始获取代码放在 React 树的根目录中,通常是 App。不要把它放在一些随机的孩子身上。至少你应该把它放在一个在你的应用程序的生命周期中存在的组件中。

将它放在componentDidMount 中的主要原因是它不能在服务器上运行,因为服务器端组件永远不会被挂载。这对于通用渲染很重要。即使您现在不这样做,您也可以稍后再这样做,并且为此做好准备是最佳实践。

【讨论】:

哇,谢谢你的回答。我回来改写我的问题,因为我问的不是很清楚,这里有一个解释为什么会发生的答案。谢谢 我从这个答案中学到了很多东西! react 非常优雅的方法 地址栏直接被Routing命中的***组件是否会多次命中componentDidMount?我很确定我已经看到了。如果有这种情况,在组件内部,除了原始帖子中的内部黑客之外,是否有办法设置组件的密钥以防止它?我不明白为什么它发生或应该是必要的。但也许我错过了什么。 一个组件只会被挂载一次。可能是组件被删除然后重新创建,或者可能有多个实例。 React 不会删除您的组件,但专利组件可能会。 所以我遇到了类似的情况。我看到了两个坐骑,从来没有一个卸载。发生的事情是我有两条路线,一条是到 /wizard 的,另一条是到 /wizard/:id 的,这导致安装了两个组件,但只渲染了一个。我很难追查为什么在某些情况下状态更改会反映在调试器中而不是其他情况下。我删除了没有参数的路线,世界再次变得美好。所以看起来组件安装了两次,但实际上是同一组件的两个独立实例。我不确定是否有调试的好方法。

以上是关于为啥 componentDidMount 在 react.js 和 redux 中被多次调用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 componentDidMount 在 react.js 和 redux 中被多次调用?

如何在 React 中使用 hooks 实现 componentDidMount 以符合 EsLint 规则“re​​act-hooks/exhaustive-deps”:“warn”?

为啥必须在 componentDidMount() 期间解析函数中的函数调用?

React componentDidMount“解析错误:缺少分号”

为啥 re.sub() 在 Python 中默认添加不匹配的字符串?

为啥 redux 多次初始化