为什么在react.js&中多次调用componentDidMount?终极版?

时间:2016-10-11 09:27:21

标签: reactjs redux react-redux

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

似乎我创建了一个递归循环。

  • componentDidMount调度获取数据的操作
  • 收到数据后,会触发成功操作以将数据存储在redux状态。
  • 父反应组件已连接到redux商店,并且对于刚刚在上一步中更改的条目具有mapStateToProps
  • parent呈现子组件(通过变量以编程方式选择)
  • 再次调用子组件的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 个答案:

答案 0 :(得分:46)

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

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

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

在您的情况下,您明确告诉React您的组件与前一个组件不同。您在每个渲染上都提供了一个新密钥。这会强制React将之前的实例视为已删除。该部件的任何儿童也未卸下并拆除。

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

如果生成一个随机密钥是正确的事情,React会为您解决这个问题。

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

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