Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>      )    })  } 
like image 228
eugene Avatar asked Oct 11 '16 09:10

eugene


People also ask

Why is componentDidMount called multiple times?

componentDidMount() only runs once after the first render. componentDidMount() may be called multiple times if the key prop value for the component changes. componentDidMount method is used for handling all network requests and setting up subscriptions during the mounting phase.

Why does React render multiple times?

The reason why this happens is an intentional feature of the React. StrictMode . It only happens in development mode and should help to find accidental side effects in the render phase. Let's find out if there is a way to avoid this problem by trying different implementations.

Why componentDidMount is called after render?

componentDidMount() method As the name suggests, after all the elements of the page is rendered correctly, this method is called. After the markup is set on the page, this technique called by React itself to either fetch the data from An External API or perform some unique operations which need the JSX elements.


1 Answers

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.

like image 112
DDS Avatar answered Oct 11 '22 07:10

DDS