How can I force component to re-render with hooks in React?

前端 未结 16 2226
误落风尘
误落风尘 2020-11-29 00:28

Considering below hooks example

   import { useState } from \'react\';

   function Example() {
       const [count, setCount] = useState(0);

       return         


        
16条回答
  •  一整个雨季
    2020-11-29 01:13

    Generally, you can use any state handling approach you want to trigger an update.

    With TypeScript

    codesandbox example

    useState

    const forceUpdate: () => void = React.useState()[1].bind(null, {})  // see NOTE below
    

    useReducer

    const forceUpdate = React.useReducer(() => ({}), {})[1] as () => void
    

    as custom hook

    Just wrap whatever approach you prefer like this

    function useForceUpdate(): () => void {
      return React.useReducer(() => ({}), {})[1] as () => void // <- paste here
    }
    

    How this works?

    "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.

    plain JS

    const forceUpdate = React.useState()[1].bind(null, {})  // see NOTE above
    const forceUpdate = React.useReducer(() => ({}))[1]
    

提交回复
热议问题