Introduction
In this article we'll show you how to force update a component in React.js. More specifically, we'll be giving a brief introduction to React re-renders, we'll show how to force updates in class-based components, and how to force updates in functional components.
React Re-Renders
React itself automatically handles re-rendering components for you, in most cases. The cause of this can be based on when props or state has been updated. So when a state or property changes, the component re-renders. But what if your component is dependent on something else and not necessarily on your state or property? In that case you may need to force update the component since React may not have detected the change.
Let's take a look at how to use this forced update on a React component. To show this, we're going to create a simple application for demo purposes.
Note: We will be covering a few concepts of React, so having basic knowledge of React is advisable.
Forcing Updates on Class-Based Components
The class component has a built-in method for re-rendering a component, called forceUpdate()
, which is used to force a component to re-render. You can read more about the forceUpdate()
method on React's official website.
handleForceupdateMethod() {
// Force a render without state change...
this.forceUpdate();
}
Note: It is not advisable to rely on updating components using the forceUpdate()
method. When you find yourself needing this method, you should first try to analyze your code and figure out if there is another reason why React is not updating the component. You may find that a bug is causing this or that you can restructure your code in a way that allows React to properly re-render the component on its own.
Here is an example of how to force an update on a class-based component:
import React from 'react'
class App extends React.Component {
constructor() {
super();
this.handleForceupdateMethod = this.handleForceupdateMethod.bind(this);
};
handleForceupdateMethod() {
this.forceUpdate();
};
render() {
return (
<div>
<h1>Hello StackAbuse</h1>
<h3>Random Number: { Math.random() }</h3>
<button onClick={this.handleForceupdateMethod}>
Force re-render
</button>
</div>
);
}
}
export default App
There's a lot more going on within this method than it may seem. For example, calling forceUpdate()
triggers the lifecycle methods for the child components as well. And as we know with React, it'll update the DOM only if the markup has actually changed.
You can access the live code here.
Forcing Updates on Functional Components
Functional components have no built-in method for re-rendering components like their class-based counterparts do. This means that we don't have the forceUpdate()
method available to us. However, recall that in React components typically re-render due to state or prop changes. Using this, we can achieve ways to force update.
As of v16.8+, React has a concept called Hooks which can be used in functional components for updating state, performing side-effects, etc. We'll use these hooks to our advantage in getting a component to re-render.
Here are some examples of how to force an update in a functional component:
Using the useReducer
hook
const [ignored, forceUpdate] = useReducer(x => x + 1, 0);
function handleClick() {
forceUpdate();
}
A reducer in React is typically used when you have complex state logic and actions. Here we use it simply to trigger the update by updating a dummy state variable, x
. The state must actually change in order to trigger the update, which is why it's incremented on each call.
Use the useState
hook
import React, { useState } from "react";
// Create your forceUpdate hook
function useForceUpdate() {
let [value, setState] = useState(true);
return () => setState(!value);
}
export default function App() {
// Call your hook here
const handleForceupdateMethod = useForceUpdate();
return (
<div className="App">
<h1>Hello StackAbuse </h1>
<h3>Random Number: { Math.random() }</h3>
{/*
Clicking on the button will force to re-render like force update does
*/}
<button onClick={handleForceupdateMethod}>Force re-render</button>
</div>
);
}
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
The idea behind this type of force update is very similar to useReducer
in that we are constantly updating state to force the change. Instead of incrementing a counter, like we did in the last method, here we simply toggle a boolean value so that it is negated on each call.
Using the useState
and useCallback
hooks
import React, { useState , useCallback} from "react";
export default function App() {
const [, updateState] = useState();
const handleForceupdateMethod = useCallback(() => updateState({}), []);
// Check your console
console.log("Rendering...");
return (
<div className="App">
<h1>Hello StackAbuse</h1>
<h3>Random Number: { Math.random() }</h3>
{/*
Clicking on the button will force to re-render like force update does
*/}
<button onClick={handleForceupdateMethod}>Force re-render</button>
</div>
);
}
Again, this strategy works by changing the state. In this case, although we're not technically changing the value of the state, we are sending it a new object, which is considered new by React since it doesn't do "deep" equality checks on state.
As you can see, there are a number of ways to achieve the same thing here. Keep in mind that these are all technically anti-patterns and should be avoided when possible. But if you're not able to resolve the underlying issue and need to force update a component, then any of the methods we've shown here should work.
Conclusion
In this article we have seen how to force updates on React components. We also saw how this can be achieved in both functional and class-based components. While not necessarily good practice, it is useful to understand how it works in case we need to use it in special cases.