How and when to force a React component to re-render

React usually automatically re-renders components, but for us to truly understand how and when to force React to re-render a component, we need to understand the inner workings of React.

Since the beginning of the web, we’ve used HTML and CSS to define the visual representation of a website. This has not changed, but, with the introduction of JavaScript, new concepts that enable us to read and update the rendered HTML of a page. We call this API DOM.

Libraries like jQuery became extremely popular because they provide an abstraction layer on top of the DOM API that provides enhanced functionality and compatibility, making it easy for developers to build web applications.

But jQuery has its limitations. It doesn’t solve crucial problems developers have when working with dynamically loaded content, such as keeping the JavaScript state (variables) and the DOM (HTML) in sync. Changing a variable in JavaScript does not affect the DOM directly.

Using a framework like React can solve this problem. React relies on JavaScript to maintain the state of an application. This master state object that contains a JavaScript reference to each object on the page is called Virtual DOM. Any changes on virtual DOM reflect automatically on the DOM, and that’s React’s best magic trick.

But how do we update the virtual DOM? We do this by building components and working with state and props.

The next question you may have is, what happens on the edge cases when a component is not updating as expected? Is it even possible? Maybe, but it’s complicated, so let’s discuss it.

Why aren’t React components re-rendering?

Generally, forcing a React component re-render isn’t 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 magic depends on us being good hosts.

Incorrectly updated state in React

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.

Incorrectly updated props without state change

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 function setMyTime and will update the variable myTime, 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());
 }

Forcing a React component to re-render

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.

Forcing an update on a React class component

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:

  • React will trigger the normal lifecycle methods for child components, including shouldComponentUpdate(), so we only can force the current component to be re-rendered
  • VirtualDOM will still validate its state with DOM, so React will only update the DOM if the markup changes

Forcing an update on a function component

There’s no official API to re-render a function component, nor is there a React Hook. There are, however, some clever tricks to signal to React that a component should be updated.

  1. 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.

2. 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.

Conclusion

In general, we should prevent forcing React to re-render components. If React fails to do re-render components automatically, it’s likely that an underlying issue in your project is preventing the components from updating correctly.

However, we covered a few common ways to force React to re-render components should it be required. Happy coding!

The post How and when to force a React component to re-render appeared first on LogRocket Blog.

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

How and when to force a React component to re-render

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.