我读到componentDidMount
在初始渲染时只被调用一次,但我看到它被渲染了多次。
我好像创建了一个递归循环。
- componentDidMount调度获取数据的操作
- 当接收到数据时,它激发成功动作以将数据存储在redux状态。
- 父react组件连接到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>
)
})
}
4条答案
按热度按时间njthzxwz1#
一个组件示例只会被装载一次,当它被删除时会被卸载。在您的情况下,它会被删除并重新创建。
key
prop的作用是帮助React找到相同组件的以前版本,这样它就可以用新的prop更新以前的组件,而不是创建一个新的组件。React通常可以在没有键的情况下正常工作,但有项目的列表除外,它需要一个键,以便在项目被重新排列、创建或删除时进行跟踪。
在您的示例中,您显式地告诉React您的组件与之前的组件不同。您在每次呈现时都提供一个新的键。这将强制React将之前的示例视为已删除。该组件的任何子组件也将被卸载和拆除。
你应该做的是不要(永远)随机生成一个密钥。密钥应该总是基于组件显示的数据的标识。如果它不是一个列表项,你可能不需要密钥。如果它是一个列表项,最好使用一个从数据标识派生的密钥,比如ID属性,或者多个字段的组合。
如果生成一个随机密钥是正确的做法,那么React会为您处理好这一问题。
你应该把初始获取代码放在React树的根目录下,通常是
App
。不要把它放在某个随机的子目录下。至少你应该把它放在一个在应用生命周期内存在的组件中。把它放在
componentDidMount
中的主要原因是这样它就不会在服务器上运行,因为服务器端的组件永远不会被挂载。这对于通用渲染很重要。即使你现在不这么做,你也可能以后再这么做,为此做好准备是一个最佳实践。332nm8kg2#
在您的组件周围使用
<React.StrictMode>
可能导致多次componentDidMount
调用。删除它后,两次调用将消失。此行为旨在帮助检测意外的副作用。您可以在文档中阅读更多相关信息。此行为仅在开发环境中发生,而在生产环境中,即使使用
<React.StrictMode>
,componentDidMount
也只调用一次。ldioqlga3#
引用一句话:
这只是因为我们在开发模式下做了两个初始渲染,以避免在引入开发工具时收到客户端/服务器标记不匹配的警告。
第一种是图像的开发模式,第二种是生产模式.
第一节第一节第一节第一节第一次
bhmjp9jg4#
我经历过componentDidMount被调用了两次。我调试了组件树,直到到达根索引。然后,我尝试删除<React.StrictMode>,结果成功了。componentDidMount只被调用了一次。这是因为<React.StrictMode>故意调用了某些React生命周期方法两次(包括componentDidMount),以帮助检测代码的潜在问题。<React.StrictMode>旨在突出显示潜在问题,如副作用、并在开发过程中发出警告。