In React class components, the forceUpdate
method is provided for forcing the re-rendering of a component.
It’s handy for situations where we want to update a component in response to changes external to the component.
However, there’s no equivalent if we use function components with React hooks.
In this article, we’ll look at how to force the re-rendering of a component created with React hooks.
useCallback Hook
One way to create a forceUpdate
function from React hooks is to use the useCallback
function.
For instance, we can write:
import { useCallback, useState } from "react";
let time = 0;
setInterval(() => {
time++;
}, 1000);
export default function App() {
const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
return (
<div className="App">
<button onClick={() => forceUpdate()}>force update</button>
<p>{time}</p>
</div>
);
}
We have the time
variable that we want to render in the App
component.
But since it’s not reactive, it won’t show the latest value unless we trigger it to re-render manually.
To create our forceUpdate
function, we create the a reactive state with the useState
hook.
We didn’t assign the returned state into a variable.
But we did assign the state change function to a variable.
upateState
is the function that we can call to force a re-render.
Next, we call the useCallback
hook to create a function that calls updateState
with a callback that calls updateState
.
useCallback
lets us cache the function so that it won’t be created repeatedly after each re-render.
updateState
will trigger an update since it changes a reactive state.
We have a button that has an onClick
handler.
onClick
is set to a function that calls forceUpdate
to force a re-render.
Once we click the button, we should see the latest value of time
at the time we clicked the button.
When we click it again, we’ll see the latest value of time
rendered.
If we want, we can also pass in a callback into our updateState
function:
import { useCallback, useState } from "react";
let time = 0;
setInterval(() => {
time++;
}, 1000);
export default function App() {
const [, updateState] = useState(0);
const forceUpdate = useCallback(() => updateState((tick) => tick + 1), []);
return (
<div className="App">
<button onClick={() => forceUpdate()}>force update</button>
<p>{time}</p>
</div>
);
}
This will also trigger a state update so a re-render will be done.
Conclusion
We can force a function component created with React hooks to re-render by updating a state.