Forcing a Re-render

Because React 7,897 bails out when a reducer returns the current state under Object.is, the inverse is also true: a reducer that returns a fresh value every time always re-renders. That is the whole trick behind the classic forceUpdate idiom.

A reducer used only for its re-renderJavaScript
const [, forceUpdate] = useReducer(x => x + 1, 0);   // the state itself is ignored
function handleExternalChange() {
  forceUpdate();                                     // no argument needed
}

useState can do the same with setTick(t => t + 1), but the reducer form is shorter and makes the intent obvious: the number is never read, only incremented.

Reaching for it usually means state is being kept somewhere React cannot see — a mutated object, a ref, a module-level variable, a library instance. The fix is almost always to move that value into useState or useReducer so the update is declared rather than forced. For a mutable external store, useSyncExternalStore (useSyncExternalStore) does the same job correctly under concurrent rendering.