Skip to content

Instantly share code, notes, and snippets.

@zetavg
Last active April 16, 2024 01:19
Show Gist options
  • Save zetavg/6fedbf89d1eb5a888e3a5ced9ac1ae0e to your computer and use it in GitHub Desktop.
Save zetavg/6fedbf89d1eb5a888e3a5ced9ac1ae0e to your computer and use it in GitHub Desktop.

onXxxIsStable

Setting this to true means that the onXxx function of the component should be treated as a stable, dependency-free function - i.e. it only references values that will not change between renders (such as refs and setState functions), and shall be safe to pass into the useCallback hook without any specifying any dependencies.

This is a performance optimization to prevent unnecessary re-renders of the component, and should only be used when the onXxx function is guaranteed to be stable.

Background:

For example, to prevent unnecessary re-renders of components that use the onValueChange prop, we would wrap the onValueChange function with useCallback. In many cases, the onValueChange function does not depend on any props or state, and can be safely wrapped with useCallback without any dependencies, such as:

<MySwitch
  value={state.myValue}
  onValueChange={useCallback(
    (myValue: boolean) =>
      setState((s) => ({
        ...s,
        myValue,
      })),
    [],
  )}
/>

However, this has some drawbacks:

  1. The code is longer and less convenient to write.
  2. TypeScript will not be able to infer the parameter type of the onValueChange function, and you will need to specify the type manually.
  3. If the component is rendered conditionally, you will not be able to use the useCallback hook inside the JSX expression, and will need to move the function definition of the onValueChange handler function to the top of the component (such as const handleMyValueChange = useCallback(...)). Sometimes, this can make the code harder to read and maintain since the handleMyValueChange function is not close to where it is used.

By using the onValueChangeIsStable prop, you can avoid these drawbacks of using useCallback to wrap the onValueChange function without dependencies to prevent unnecessary re-renders of the component, as the component will simply ignore the onValueChange prop when comparing props for re-renders:

<MySwitch
  value={state.myValue}
  onValueChangeIsStable
  onValueChange={(myValue) =>
    setState((s) => ({
      ...s,
      myValue,
    }))
  }
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment