为什么在 react.js & 中多次调用 componentDidMount还原? [英] Why componentDidMount gets called multiple times in react.js & redux?

查看:82
本文介绍了为什么在 react.js & 中多次调用 componentDidMount还原?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

如何停止循环?

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

 function renderSubviews({viewConfigs, viewConfig, getSubviewData}) {返回 viewConfig.subviewConfigs.map((subviewConfig, index) => {让 Subview = viewConfigRegistry[subviewConfig.constructor.configName]让 subviewData = getSubviewData(subviewConfig)const key = shortid.generate()const subviewLayout = Object.assign({}, subviewConfig.layout, {key: key})返回 (

)})}

解决方案

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

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

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

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

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

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

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

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

I read componentDidMount gets called only once for initial rendering but I'm seeing it's getting rendered multiple times.

It seems I created a recursive loop.

  • componentDidMount dispatches action to fetch data
  • upon receiving the data, it fires success action to store the data in redux state.
  • a parent react component is connected to redux store and has mapStateToProps for the entry that just changed in the above step
  • parent renders child components (which is programmatically selected via variable)
  • the child component's componentDidMount gets called again
  • it dispaches action to fetch data

I think that's what's happening. I may be wrong.

How can I stop the loop?

Here's the code for programmatically rendering child components.

 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>
     )
   })
 }

解决方案

A component instance will only get mounted once and unmounted when it gets deleted. In your case it gets deleted and recreated.

The point of the key prop is to help React find the previous version of the same component. That way it can update a previous component with new props rather than create a new one.

React can often work fine without a key, the exception being a list with items. It wants a key there so it can keep track when items get rearranged, created or deleted.

In your case, you are explicitly telling React that your component is different from the previous one. You're giving a new key on each render. This forces React to treat the previous instance as having been deleted. Any children of that component are also unmounted and dismantled.

What you ought to do is not (ever) generate a key at random. Keys should always be based on the identity of the data a component is displaying. If it's not a list item you probably don't need a key. If it is a list item, it's much better to use a key derived from the data's identity, such as an ID property, or maybe a combination of multiple fields.

If generating a random key would have been the correct thing to do, React would have just taken care of that for you.

You should place your initial fetch code in the root of your React tree, usually that's App. Don't put it in some random child. At least you should put it in a component that exist for the lifetime of your app.

The main reason to put it in componentDidMount is so it doesn't run on the server, because server-side components never get mounted. This is important for universal rendering. Even if you're not doing this now, you might do this later, and being prepared for it is a best practice.

这篇关于为什么在 react.js &amp; 中多次调用 componentDidMount还原?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆