I have a simple React application in which the index.js file looks like this:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
For some reason, this causes the App
component to be rendered twice (evinced by console logs in App
). When I remove <React.StrictMode>
, it renders only once:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
//<React.StrictMode>
<App />
//</React.StrictMode>
);
When I googled this, I found this (https://react.dev/reference/react/StrictMode) which says:
Your components will re-render an extra time to find bugs caused by impure rendering. Your components will re-run Effects an extra time to find bugs caused by missing Effect cleanup.
Is there any way to prevent the double rendering caused by StrictMode
? For example, a child component to the App
component contains a timer set by setTimeout
. Because of the double rendering, this timer is created twice, which has unwanted side effects. <-- Can this be fixed or worked around?
StrictMode is a developmental aid. It points out the components which must be equipped with cleanup functions to revert the side effects, and retain them as pure components.
It checks components for its purity, and provides some ways for early detection - during the development itself. It does not have any impact in Production.
A pure component is the one which returns the same output for the same inputs, irrespective of the number times it has been invoked. A pure function is like a formula. For the same inputs, it will give the same outputs, no matter how many times it has been invoked.
Let us take formula :
y = 2x;
if x = 2, then y will be 4, always, no matter how many times it has been called. Therefore it is pure.
Let us create a function in React which does the same function as the formula. Every invocation of this component will result double of the given value. Always. Therefore it is also pure.
function FormulaOne(x) {
return 2 * x;
}
However, let us take a different case shown below.
By rendering the below App in development, we expect it to give 1 as the output, but it gives 2. This is due to the double mounting of the same component which React does for testing its purity. However if the component was pure, it would have returned the same expected result. Therefore the double mounting is very useful to detect errors if any.
export default function App() {
return (
<>
<FormulaTwo x={1} />
</>
);
}
let mulfactor = 0;
function FormulaTwo({ x }) {
mulfactor++;
return <>{mulfactor * x}</>;
}
Now to address the impure component discussed above, the side effect it has made must be reverted on each unmount event of the component. This is where the need of a cleanup function comes in for a component.
Let us fix the impure component by a clean up function as below. From now on, this function will act as a pure one. Calling it multiple times with the same input will result the same output. Now when we run it, we get 1 even though the double mounting still has been happening. The cleanup function reverts the side effect on each unmount event and thus and keeping the function pure.
import { useEffect } from 'react';
export default function App() {
return (
<>
<FormulaTwo x={1} />
</>
);
}
let mulfactor = 0;
function FormulaTwo({ x }) {
mulfactor++;
useEffect(() => {
return () => {
mulfactor--;
};
});
return <>{mulfactor * x}</>;
}
The Answer to the question is : implement cleanup functions and retain the components pure.