useForceUpdate is a hook that returns a function to force a component re-render. Optionally, you can provide a callback that will be executed before the re-render is scheduled.
function useForceUpdate(): (onBeforeUpdate?: () => void) => void;- Returns
- A function
forceUpdate(onBeforeUpdate?)that triggers a re-render. IfonBeforeUpdateis provided, it is called synchronously before the re-render is scheduled.
- A function
import { useRef } from 'react';
import { useForceUpdate } from '@webeach/react-hooks/useForceUpdate';
export function RefCounter() {
const forceUpdate = useForceUpdate();
const countRef = useRef(0);
const increment = () => {
countRef.current += 1; // imperative mutation outside React state
forceUpdate(); // trigger re-render to show the new value
};
return (
<button onClick={increment}>
count = {countRef.current}
</button>
);
}import { useForceUpdate } from '@webeach/react-hooks/useForceUpdate';
export function WithCallback() {
const forceUpdate = useForceUpdate();
const handleClick = () => {
forceUpdate(() => {
console.log('Before re-render');
});
};
return <button onClick={handleClick}>Refresh</button>;
}-
Stable reference
- The returned function is stable across renders; safe to use in effect or callback dependencies.
-
onBeforeUpdateexecution- If provided,
onBeforeUpdateis called synchronously before scheduling a re-render.
- If provided,
-
Batched updates
- Multiple calls within the same tick may be batched by React into a single re-render.
-
Use case
- Ideal for syncing UI with external imperative changes that React state does not track.
- Integrating with imperative or external APIs (editors, maps, widgets) where internal changes are not tracked by React.
- Rare cases where moving state into React is impossible or too complex.
- If you can manage state with
useState,useReducer, or Context — prefer those. - For external stores or event emitters, consider
useSyncExternalStoreor a subscription-based approach instead of forcing updates.
-
Passing
forceUpdatedirectly as an event handler- Using
onClick={forceUpdate}will pass the event object asonBeforeUpdateand attempt to call it as a function, causing an error. Use a wrapper:onClick={() => forceUpdate()}or pass a valid callback:onClick={() => forceUpdate(() => {/* ... */})}.
- Using
-
Infinite render loops from effects
- Calling
forceUpdate()inside an effect without conditions leads to continuous re-renders. Always add guards or dependencies.
- Calling
-
Expecting
onBeforeUpdateto run after render- The callback runs before re-render. For post-render logic, use
useEffectoruseLayoutEffect.
- The callback runs before re-render. For post-render logic, use
Exported types
UseForceUpdateReturn- Function signature:
(onBeforeUpdate?: () => void) => void.
- Function signature: