我读componentDidMount
只被调用一次进行初始渲染,但我看到它被多次渲染。
似乎我创建了一个递归循环。
mapStateToProps
我认为这就是发生的事情。我可能错了。
如何停止循环?
以下是以编程方式呈现子组件的代码。
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>
)
})
}
答案 0 :(得分:46)
组件实例只会挂载一次,并在删除时卸载。在您的情况下,它将被删除并重新创建。
key
道具的目的是帮助React找到同一组件的先前版本。这样,它可以使用新的道具更新以前的组件,而不是创建一个新组件。
在没有密钥的情况下,React通常可以正常工作,例外是带有项目的列表。它需要一个密钥,以便在重新排列,创建或删除项目时跟踪它。
在您的情况下,您明确告诉React您的组件与前一个组件不同。您在每个渲染上都提供了一个新密钥。这会强制React将之前的实例视为已删除。该部件的任何儿童也未卸下并拆除。
你应该做的不是(永远)随机生成密钥。密钥应始终基于组件正在显示的数据的标识。如果它不是列表项,您可能不需要密钥。如果它是列表项,则使用从数据标识中派生的密钥(例如ID属性)或多个字段的组合会更好。
如果生成一个随机密钥是正确的事情,React会为您解决这个问题。
您应该将初始提取代码放在React树的根目录中,通常是App
。不要把它放在一些随意的孩子身上。至少你应该将它放在应用程序生命周期中存在的组件中。
将它放在componentDidMount
中的主要原因是它不能在服务器上运行,因为服务器端组件永远不会被挂载。这对于通用渲染很重要。即使您现在没有这样做,您也可以稍后再这样做,并为此做好准备是最佳做法。