score:31

Accepted answer

I would assume that this is normal. If you aren't having noticeable performance issues, I wouldn't sweat it. If performance begins to be a problem, you can look into overriding the shouldComponentUpdate lifecycle method if you are certain that certain state changes won't change the rendered component.

Edit: You could also look into extending React.PureComponent instead of React.Component if you only need shallow comparison in your shouldComponentUpdate lifecycle method. More info here.

score:0

removing <React.StrictMode> worked on my case too

score:1

If using >v16.3, then try removing <React.StrictMode> and it should work fine.

Why? Since v16.3 for class components and v16.8 for hooks , React introduced <React.StrictMode> in order to make the transition to Concurrent React ( in the near future ) more developer friendly, since render phase can be invoked multiple times then.

The following articles are read worthy:

React Components rendered Twice

React Components render twice and drive me crazy

Wait, you're not using <React.StrictMode>?!

Note: This is applicable to dev env only.

score:4

This is an old question, I see, but I also noted this issue. Like noted in Donald's answer, it seems to be normal. I tried three things to troubleshoot my specific case:

  • I turned off the React DevTools plugin to see if it was the cause of the duplicate messages.
  • I checked a different browser to see if that was the issue.
  • I created a short test to check if it happens on simple components.

The first two methods

Disabling the React DevTools plugin did not change the number of messages logged into the console.

Changing browser also had no effect. I tried Chromium and Firefox.

The third method

Even the simplest components seem to call the life cycle methods more than once.

Given two files, App.js and components/TestComponent.js, as follows:

// App.js

import React from 'react';
import './App.css';
import Test from './components/TestComponent';

function App()  {
  console.log('App render');
  return ( 
      <div>
        <Test />
      </div>
  
  );
}

export default App;
// ./components/TestComponent.js

import React, { Component } from 'react';


class Test extends Component {
  constructor(props) {
    console.log('Test constructed');
    super(props);
    
  }

  componentDidMount() {
    console.log('Test mounted');
  }

  componentDidUpdate() {
    console.log('Test updated');
  }

  render() {
    console.log('Test rendered');
    return (
      <div>
        <h1>Hello, world!</h1>
      </div>
    );
  }
}

export default Test;

Life cycle methods of Test are called multiple times.

Notes

  • I used create-react-app to set up the app.
  • The react version is 16.13.1.

Results and discussion

With yarn start, I get the following in the console:

App render
TestComponent.js:7 Test constructed
TestComponent.js:7 Test constructed
TestComponent.js:20 Test rendered
TestComponent.js:20 Test rendered
TestComponent.js:12 Test mounted

For me, at least, yarn notes that the development build is not optimized, and running yarn build and then serving it with python -m http.server --directory build gives a page that doesn't have the duplicate messages.

As for why you're getting three renders instead of two, I can't say. My suggestion is to try building the app and seeing if the problem persists in the production build.

If you still encounter the issue, you can also go with Donald's suggestion to implement logic in shouldComponentUpdate.

score:37

If you are setting state at three different stages then the component will re-render three times as well.

setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate().

(source)

You can implement logic in shouldComponentUpdate() to prevent unneeded re-renders if you are experiencing performance issues.


Related Query

More Query from same tag