React component render is called multiple times when pushing new URL
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
.
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.
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.
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.