Considering below hooks example
import { useState } from \'react\';
function Example() {
const [count, setCount] = useState(0);
return
Generally, you can use any state handling approach you want to trigger an update.
codesandbox example
const forceUpdate: () => void = React.useState()[1].bind(null, {}) // see NOTE below
const forceUpdate = React.useReducer(() => ({}), {})[1] as () => void
Just wrap whatever approach you prefer like this
function useForceUpdate(): () => void {
return React.useReducer(() => ({}), {})[1] as () => void // <- paste here
}
"To trigger an update" means to tell React engine that some value has changed and that it should rerender your component.
[, setState]
from useState()
requires a parameter. We get rid of it by binding a fresh object {}
.
() => ({})
in useReducer
is a dummy reducer that returns a fresh object each time an action is dispatched.
{}
(fresh object) is required so that it triggers an update by changing a reference in the state.
PS: useState
just wraps useReducer
internally. source
NOTE: Using .bind with useState causes a change in function reference between renders. It is possible to wrap it inside useCallback as already explained here, but then it wouldn't be a sexy one-liner™. The Reducer version already keeps reference equality between renders. This is important if you want to pass the forceUpdate function in props.
const forceUpdate = React.useState()[1].bind(null, {}) // see NOTE above
const forceUpdate = React.useReducer(() => ({}))[1]