In functional components, there's no built-in method for forcing re-rendering, like in class components where we have forceUpdate()
. However, in React, components typically re-render due to state or prop changes.
Given this, there are a few ways to force a re-render in a functional component.
Since version 16.8+, React introduced the concept of Hooks, which can be used in functional components to update the state, trigger side effects, and more. We'll use these hooks to our advantage to force a component re-render.
Below are a few examples of how to trigger a re-render in a functional component:
Note: These techniques should only be used in exceptional cases. Ideally, components should re-render only when their state or props change.
Re-render a Functional Component Using useReducer
import React, { useReducer } from "react";
const [ignored, forceUpdate] = useReducer((x) => x + 1, 0);
function handleClick() {
forceUpdate();
}
useReducer
is generally used when you have complex state logic and actions. In this case, we use it simply to trigger an update by incrementing a dummy state variable, x
. Since state must change to trigger an update, x
is incremented each time.
Force Component Update with useState
import React, { useState } from "react";
// Create a custom hook that uses useState to force an update
const useForceUpdate = () => useState()[1];
// Call the custom hook inside a component
const Hooks = () => {
const forceUpdate = useForceUpdate();
return <button onClick={forceUpdate}>Update me</button>;
};
The example above mirrors the behavior of forceUpdate
in class components. Here's how the custom hook works:
The useState
hook returns an array with two elements: the current state value and a state updater function.
In this case, we immediately invoke the updater function without passing any value, which effectively calls set...()
with undefined
. This forces React to re-render the component, even though no meaningful state change occurred.
As you can see, there are several ways to achieve the same outcome. Remember, these are technically anti-patterns and should be avoided when possible. However, if you're unable to resolve the root issue and need to force a component re-render, any of the methods shown here should work.