React automatically Re-Renders the components whenever any of its props or its state is updated. But quite often beginners (especially me in my early days) find it quite difficult getting a component re-rendered.
First, let's look at the methods we can use to re-render a component, and discuss whether we should really force a re-render or let React take care of it.
Re-Render a Class Component
Class Components provide you a built-in method to trigger a Re-Render. Simply use forceUpdate
method to force React to Re-Render the component.
class App extends React.Component{
constructor(){
super();
this.forceUpdateHandler = this.forceUpdateHandler.bind(this);
};
forceUpdateHandler(){
this.forceUpdate();
};
render(){
return(
<div>
<button onClick={this.forceUpdateHandler}>
Change Number
</button>
<h4>Random Number : { Math.random() }</h4>
</div>
);
}
}
Re-Render a Functional Component
Unfortunately, Functional Component doesn't have a forceUpdate
method for ease of use. You can use useState
hook to simulate an update or create a custom hook too.
// forceUpdate hook
function useForceUpdate() {
const [value, setValue] = useState(0);
return () => setValue((value) => value + 1);
}
// component
function App() {
const forceUpdate = useForceUpdate();
return (
<div>
<button onClick={forceUpdate}>
Change Number
</button>
<h4>Random Number : { Math.random() }</h4>
</div>
);
}
Should you Force Re-Render a React Component?
Now for answering the most important question...
NO! NO! and NO!!!!!!!!!!
In most cases, you DEFINITELY SHOULD NOT force a re-render!
There are a few niche cases, like modifying a blockchain (which only returns a transaction hash and no data), where the forced re-render makes sense to fetch the updated data from the blockchain.
Debugging Why the Component isn't Updating
Let's look at some of the common issues why React fails to update your components and find solutions for them as well.
1. Incorrectly Updated State
Let's consider the following example:
const App = () => {
const [user, setUser] = useState({ name: "", age: 0, });
const updateUser = () => {
user.name = "Tom";
setUser(user)
}
return (
<>
<h2>Name: {user.name}</h2>
<button onClick={updateUser}>
Update User
</button>
</>
);
}
The App
component would not be re-rendering the user's name even when the Update User
button is clicked.
React evaluates state changes by checking its shallow equality (also called reference equality), which checks to see if both the current and the new value for state reference the same object. In our example, we updated one of the properties of the user object, but we technically made setUser
the same object reference, and thus, React didnβt perceive any change in its state.
As React documentation mentions, State should be treated as immutable.
So, how do we fix it? We could create a new object with the updated values:
const updateUser = () => {
setUser({
...user,
name: "Tom",
})
}
2. Incorrectly Updated Props (without state change)
Incorrectly updating props without a state change can also leads to bugs. Letβs look at an example:
let time = new Date();
// setInterval(() => {
// console.log(time)
// }, 1000);
const App = () => {
useEffect(() => {
const intervalId = setInterval(() => {
time = new Date()
}, 1000);
return () => clearInterval(intervalId);
}, []);
return (
<Clock time={time} />
);
}
The Clock
in the example doesn't update the time
after the first load. To confirm that the time
is being properly updated, you can just un-comment the console.log
. Every second, the runtime will update the variable time
, which is then passed to our Clock
component for rendering.
When the state changes, App
(parent component) is re-rendered, thus triggering a re-rendered in Clock
(child component) with the updated time
. Thus updating state is what actually triggers the re-render, which is then propagated through the props. So updating the state is ABSOLUTELY CRUCIAL!
So to fix the issue, we could use the following:
const App = () => {
const [time, setTime] = useState(new Date());
useEffect(() => {
const intervalId = setInterval(() => {
setTime(new Date());
}, 1000);
return () => clearInterval(intervalId)
}, [])
return (
<Clock time={time} />
);
}
Wrapping up
Just like everything in this world, this article too has to end π
In the article, we went through some of the ways you can force re-render your React Components as well as the common causes of why React fails to re-render the components. Hope this helps you.
Best of Luck with your React Development Journey!
Finding personal finance too intimidating? Checkout my Instagram to become a Dollar Ninja
Thanks for reading
Need a Top Rated Front-End Development Freelancer? Contact me on Upwork
Want to see what I am working on? Check out my GitHub
I am a freelancer who will start off as a Digital Nomad in mid-2022. Want to catch the journey? Follow me on Instagram
Follow my blogs for Weekly new Tidbits on Dev
FAQ
These are a few commonly asked questions I get. So, I hope this FAQ section solves your issues.
-
I am a beginner, how should I learn Front-End Web Dev?
Look into the following articles: Would you mentor me?
Sorry, I am already under a lot of workload and would not have the time to mentor anyone.Would you like to collaborate on our site?
As mentioned in the previous question, I am in a time crunch, so I would have to pass on such opportunities.
Connect to me on
Top comments (7)
React automatically Re-Renders the components whenever any of its props ... we should really force a re-render or let React take care of it. Signs Of Black Magic Done On You
That's exactly what I pointed out: React re-renders a component when the state data changes. If the props contains a state data from the parent component, a re-rendered is triggered for it too, else it fails to re-render. The fix for it is provided above too & there is no need to force a re-render
Try out the code provided in the example to see for yourself
Hello!
You should replace
clearInterval(intervalId) with
() => clearInterval(intervalId),
in your case the interval will clear immediately.
Yeah, thanks a lot for pointing it out! A rather silly mistake on my part
I think the best way to force rendering is using key property on an component.
Change it and the component will update.
Could you share an example snippet?
Check this good article from Kent C. Dodds, the last part with a Counter example show how to use a key to reset a component telling React to unmount and mount the component.
kentcdodds.com/blog/understanding-...
To use with great responsibility in mind :)