为什么 componentDidMount 在 react.js & redux 中被多次调用?

Why componentDidMount gets called multiple times in react.js & redux?

我读到 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>
     )
   })
 }

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

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

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

在你的例子中,你明确地告诉 React 你的组件与之前的组件不同。您在每个渲染器上都提供了一个新密钥。这会强制 React 将先前的实例视为已被删除。该组件的任何 children 也将被卸载和拆除。

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

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

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

将它放在 componentDidMount 中的主要原因是它不会 运行 在服务器上,因为 server-side 组件永远不会被安装。这对于通用渲染很重要。即使您现在不这样做,以后也可能会这样做,最好为此做好准备。

就一个quote:

It's just because we do 2 initial renders in dev mode to avoid getting warnings about mismatched client/server markup when we introduce the devtools. Doesn't affect production.

第一张图-开发模式,第二张-生产模式。

我发现在组件周围使用 <React.StrictMode> 可能会导致多次 componentDidMount 调用。删除它后,双重调用就消失了。

似乎这只发生在开发环境中,而在生产环境中 componentDidMount 即使使用 <React.StrictMode> 也只被调用一次。

“这是用 React 18.1.0 测试的”