Here's how to force a re-render in React. ⚛
Vaibhav Khulbe
Posted on October 30, 2020
Hey there React developers! Do you struggle with unnecessary re-renders of components in your application?
We all must have gone through this phase when one component just keeps on updating its data in the background and then the overall performance takes a hit!
Most of the time when you start optimizing the code to the best of your knowledge you can assume that it is a very complex and tiring process because everything in React happens so fast when it updates the DOM.
Also, the fact that the DOM was updated doesn't mean that it was actually modified by your changes. Well, then how do you stop this from happening or how would you rather force the Render? In this article, we're about to see exactly how.
A quick note on Render 📝
React's
createElement()
function creates and returns a new element according to the element of the given type.
Whether it's the props
or the children
, all the updates are done automatically only when it's needed. Based on what JSX we write for the DOM, React creates a virtual instance of it called the Virtual DOM. This whole process of updating the DOM always consists of the following three stages:
Render: this renders the React element into the DOM, returning a reference to the component. The output is taken from the
createElement
function.Reconciliation: using the Diffing Algorithm, new elements are compared against previously elements and if there is a difference, the virtual DOM is updated.
Commit: finally, the stage where the real changes (DOM updation) are made.
Let's see how the re-render is done in both the class and functional component types.
Forcing a re-render in a class component
This is pretty straightforward. We can use the forceUpdate()
function provided by the React API. It takes the following syntax:
component.forceUpdate(callback)
This is highly useful when the rendering depends on some other data apart from the state and you need React to re-render that specific component. The process is achieved by skipping the shouldComponentUpdate()
lifecycle Hook.
Now if you compare the setState
with forceUpdate
, you will get to know that the latter will update a component even if the shouldComponentUpdate
is implemented.
⚠️ Pssst. Wait wait! There's a warning here though. You should try to avoid all uses of forceUpdate()
and instead read from this.props
and this.state
in render()
.
Now, what is the solution then?
Re-render when state changes
Make use of the render()
method and setState()
.
The whole purpose of setState
is to add changes in the queue to the component's state and it tells React that this component and its children need to be re-rendered with the updated state. This takes in the following syntax:
setState(updater, [callback])
Let's update the state of a component when it mounts.
class App extends React.Component {
componentDidMount() {
this.setState({});
}
render() {
console.log('Render is invoked')
return <h1>Hi!</h1>;
}
}
Here, we used the componentDidMount()
lifecycle Hook to update the state.
Another example is for an event in a component:
class App extends React.Component {
state = {
msg: ""
};
handleClick = () => {
this.setState({ msg: "Updated!" });
};
render() {
console.log('Render is invoked');
return (
<>
<button onClick={this.handleClick}>Click me</button>
<div>{this.state.msg}</div>
</>
);
}
}
In this case, with the click of a button, we update the state.
Forcing a re-render in a functional component
Like in a class component, we don't have the flexibility to choose forceUpdate
. But we can surely go close to it as much as we like to by using the concept of React Hooks.
Specifically, if we use the useState
Hook, for a simple counter app, where on the onClick
of a button, we increase the previous count inside the setter function of useState
(for example: setCount
). This is exactly the point where we need to force the re-render of the counter component.
Here's a relatable example:
import React, {useState} from ‘react’;
const App = props => {
const [count, setCount] = useState(0)
const onClickHandler = event = => {
setCount(count => count + 1)
}
return (
<button onClick={onClickHandler}>Click me</button>
)
}
You can even go ahead and write your own custom Hook according to the need. It will work the same way just that this time you will have control over this Hook to add multiple points where you need a re-render.
Where to next? 🤔
Make your re-render count by visiting the following resources that talk more about different case scenarios and examples:
📄 React render()
documentation
Force Component to re-render With Hooks in React | by Harsh Patel | Weekly Webtips | Medium
Harsh Patel ・ ・
Medium
I have an external (to the component), observable object that I want to listen for changes on. When the object is updated it emits change events, and then I want to rerender the component when any change is detected.
With a top-level React.render
this has been possible, but within a…
Thanks for reading, I appreciate it! Have a good day. (✿◕‿◕✿)
TIME TO GET TO WORK! 😀
— Microsoft Developer UK (@msdevUK) October 29, 2020
Image source: https://t.co/t9tnTL53go#DevHumour #SQL #BigData pic.twitter.com/vblvcTRpqL
📫 Subscribe to my weekly developer newsletter 📫
PS: From this year, I've decided to write here on DEV Community. Previously, I wrote on Medium. If anyone wants to take a look at my articles, here's my Medium profile.
Posted on October 30, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 2, 2024