Editor’s note: This article was last updated on 13 October 2023 to include information about the methods for re-rendering in React, including the setState
method and the forceUpdate
method, as well as information about when not to force a component to re-render.
React is usually good at knowing when it’s time to update a component. But there are moments when we want to take the reins and tell it to refresh a certain part of the codebase. That’s exactly what we’re going to explore in this article: we’ll dive deep into the world of React components and learn how to forcefully re-render them.
Think of force re-rendering in React like pressing the refresh button on a webpage, even when the page seems just fine. In the React world, it means telling a component to update and redraw itself, even if nothing has really changed in the data (state/props) it uses.
Let’s take a closer look at how React’s rendering process works by default. To understand when and why you might need to nudge React into re-rendering, you need to get familiar with its underlying architecture.
At the heart of React’s rendering magic lies the Virtual DOM. Imagine it as a clone of the actual DOM, the structure of your webpage. React uses this Virtual DOM to figure out what needs to be updated when your data changes. It’s like having a duplicate house to practice your painting skills on before touching the real thing.
So, how does React know when to refresh the Virtual DOM and make necessary changes to the actual web page? This happens in three stages:
Understanding these stages is crucial because it provides insights into React’s default rendering behavior. And it also helps us know when and how to intervene with force re-rendering when needed. So, as we explore further, we’ll dive into when you might want to guide React through these stages and ensure your components stay in sync with your application’s state.
Generally, forcing a React component to re-render isn’t the best practice, even when React fails to update the components automatically. So, before considering forcing a re-render, we should analyze our code, as React depends on us being good hosts.
Let’s build a simple component to demonstrate one common reason components aren’t rendering. We will build a simple app that will show a username, Juan
, and, after pressing a button, the name will change to Peter
.
Here is a demonstration of the app with the complete code. You probably noticed that after clicking the button, nothing happens, even though we changed our state on the button:
function changeUserName() { user.name = "Peter"; setUser(user); }
The component did not change, so there was no re-rendering trigger. Here’s why.
React evaluates state changes by checking its shallow equality (or reference equality), which checks to see if both the preview and 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.
State, as described in the React documentation, should be treated as immutable. So, how do we fix it? We could create a new object with the correct values as follows:
function changeUserName() { setUser({ ...user, name: "Peter" }); }
Note that we are using the spread operator in JavaScript to preserve the properties of the original object while updating its name
property under a new object. The final result can be observed here.
While it may seem impossible, incorrectly updating props without a state change can happen, and it usually leads to bugs. Let’s look at an example.
In this demo, I built a clock that has a major problem: the time doesn’t change after I first load the screen. Not a very useful clock, right?
Let’s take a look at the code responsible for calculating the current time:
let myTime; function setMyTime() { myTime = new Date(); setTimeout(() => { setMyTime(); }, 1000); } setMyTime();
This code looks ugly and is generally not a great way to code for a React component, but it works. Every second, the runtime will call the setMyTime
function and will update the myTime
variable, which is then passed to our Clock
component for rendering:
<Clock myTime={myTime} />
This demo doesn’t work because props are a reflection of state, so a standalone change in props won’t trigger a re-render. To fix it, we need a total rewrite.
Notice that we introduced state to manage myTime
and useEffect
to start and clear the timers to avoid bugs when the component re-renders. And it works:
const [myTime, setMyTime] = useState(new Date()); useEffect(() => { var timerID = setInterval(() => tick(), 1000); return () => clearInterval(timerID); }); function tick() { setMyTime(new Date()); }
React provides us with multiple ways to tell when to re-render the component. There are three ways we will discuss below:
setState
method: This is the go-to method for most re-rendering scenarios. When you call setState
, React takes notice and starts the re-rendering process for the component. It’s like telling your component, “Hey, something’s changed, time to update!” You typically use this method when your component’s state or props changeforceUpdate
method: Sometimes, you might have a good reason to bypass the usual state or prop changes and refresh your component entirely. The forceUpdate
function does just that. It’s like giving your component a direct order to repaint itself, regardless of what’s happening in the background. Use this one sparingly, as it can disrupt React’s optimizationkey
prop manipulation: This is a more advanced technique. React relies on keys to determine which elements in a list have changed. By manipulating the key prop, you can effectively force re-renders in components that rely on lists. It’s a bit like changing the name on the mailbox to get your mail forwarded to a different address. It’s useful in specific scenarios, but use it with careThese methods provide you with the means to control when and how your components re-render. Remember that with great power comes great responsibility. Overusing these methods can lead to issues, which we will discuss later in this article.
It’s typically frowned upon to force a component to re-render, and the failure of automatic re-rendering in React is often due to an underlying bug in our codebase. But, if you have a legitimate need to force a React component to re-render, there are a few ways to do it.
If you are using class components in your code, you’re in luck. React provides an official API to force a re-render, and it’s straightforward to implement:
someMethod() { // Force a render without state change... this.forceUpdate(); }
In any user or system event, you can call the method this.forceUpdate()
, which will cause render()
to be called on the component, skipping shouldComponentUpdate()
, and thus, forcing React to re-evaluate the Virtual DOM and DOM state.
There are some caveats to this method:
shouldComponentUpdate()
, so we can only force the current component to be re-renderedThere’s no official API to re-render a function component, nor is there a React Hook. However, there are some clever tricks to signal to React that a component should be updated.
Replace state objects with a new instance of themselves
Let’s say we want to force a refresh on our change user example above. We could do something like this:
someMethod() { // Force a render with a simulated state change setUser({ ...user }); }
Because user
is an object, we could copy it to a new object and set it as the new state. The same could apply to any other object or array.
Have an empty state variable trigger updates
This method is interesting, as it creates a new object in the state. We only care about its update
function as follows:
const [, updateState] = React.useState(); const forceUpdate = React.useCallback(() => updateState({}), []);
Here, we use useCallback
to memoize our forceUpdate
function, thus keeping it constant throughout the component lifecycle and making it safe to be passed to child components as props
.
Here is an example of how to use it:
import React from "react"; export default function App() { const [, updateState] = React.useState(); const forceUpdate = React.useCallback(() => updateState({}), []); console.log("rendering..."); return ( <div className="App"> <h1>Time to force some updates</h1> <button onClick={forceUpdate}>Force re-render</button> </div> ); }
Now, each time we click on the Force re-render button, the component will re-render. You can access the live demo here.
While we’ve learned that force re-rendering can be a handy tool, there are situations where you should think twice before hitting that refresh button. There are many unintended consequences to doing this, some of which are listed below:
In essence, while force re-rendering is a powerful tool, it’s not a magic wand to solve all issues. Use it wisely, with a clear understanding of when and why it’s necessary. When it comes to React, sometimes, less is more. Only give your components a makeover when they truly need it, and your React app will thank you for it.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowDing! You got a notification, but does it cause a little bump of dopamine or a slow drag of cortisol? […]
A guide for using JWT authentication to prevent basic security issues while understanding the shortcomings of JWTs.
Auth.js makes adding authentication to web apps easier and more secure. Let’s discuss why you should use it in your projects.
Compare Auth.js and Lucia Auth for Next.js authentication, exploring their features, session management differences, and design paradigms.
3 Replies to "How and when to force a React component to re-render"
Thanks for this. It really helped me. I had the same problem where I assigned a variable a reference to the actual state object and that cause the component not to rerender.
One of the best articles I have read on react because it cuts to the heart of the library. Amazing!!! Thank you and thank you LogRocker for facilitating great content 🙂
I was stuck with issues for a few hours and as we all know how to react rendering is frowned upon. Will try to do it now using the manual method and see what happens!