Reputation: 517
I have a simple functional component with a boolean state. And buttons to change the state.
It is initially set to true
so when I press the true-button, it does NOT render.
But if I press the false-button, it re-renders AND if I press false-button AGAIN, it will re-render even though the state is already set to false
..
Could someone explain why the component re-renders when the state changes to the exact same state? How to prevent it from re-rendering?
import React, {useState} from 'react';
const TestHooks = () => {
const [state, setState] = useState(true);
console.log("rendering..", state);
return(
<div>
<h1>{state.toString()}</h1>
<button onClick={() => setState(true)}>true</button>
<button onClick={() => setState(false)}>false</button>
</div>
)
}
export default TestHooks;
Upvotes: 9
Views: 8641
Reputation: 12711
From the react docs :
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)
Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree. If you’re doing expensive calculations while rendering, you can optimize them with useMemo.
So your component will not re-render every time setState
is called with the same state. It will re-render only 2 times and then bail out. That's just how react works and that should not be a concern except if you're doing some heavy calculations in the render method.
Upvotes: 13
Reputation: 801
render()
will be called whenever setState()
is called. That is the reason why we have the concept of PureComponent
in React. Read https://reactjs.org/docs/react-api.html#reactpurecomponent
Upvotes: -1
Reputation: 15698
It doesn't matter if the state
value is already the same as the one you are trying to update it with. The fact is, setState()
will re-render your component regardless, that's just what React does to ensure all changes (if any) are reflected in the UI.
If you want to avoid unnecessary re-renders, use an intermediary function to check if the state values are already equal before updating it.
import React, {useState} from 'react';
const TestHooks = () => {
const [state, setState] = useState(true);
const updateState = (boolean) => {
if(boolean !== state){
setState(boolean)
}
}
console.log("rendering..", state);
return(
<div>
<h1>{state.toString()}</h1>
<button onClick={() => updateState(true)}>true</button>
<button onClick={() => updateState(false)}>false</button>
</div>
)
}
export default TestHooks;
Upvotes: 1