Search code examples
reactjsreact-hooksredux-toolkit

Are there performance gains for useCallback and useMemo with redux-toolkit?


I've seen a lot of descriptions of why you shouldn't use React's useCallback with an empty dependency list (which makes logical sense), but I'm stuck trying to figure out if there are performance gains when using it alongside redux-toolkit, when the dependency list includes RT objects. (The application is already performant enough with one user that there's no perceptible difference, so I'm looking to do the "right thing" in the aggregate.)

An example:

export const HomeSettings = () => {
  // redux-toolkit
  const { data, error, isLoading } = useGetUserQuery();
  const [updateUser] = useUpdateUserMutation();

  //useCallback providing an actual optimization here?
  const changeDataFilterOption = useCallback(
    (option: string) => {
      const someObj = someFunc(option, data);
      updateUser(someObj);
    },
    [data, updateUser]
  );

  //useMemo optimizing anything here?
  const itemList = useMemo(() => getListOfThings(data), [data]);

  if (isLoading) {
    return <LoadingMessage />;
  }
  if (error) {
    return <ErrorLoadingDataMessage />;
  }

  return (
    <div onClick={changeDataFilterOption}>
      onClick is silly here, just illustrating the point
      <div>{itemList}</div>
   </div>
  );
}

Using redux-toolkit in this way, is there any benefit to memo-izing my callbacks and variables?


Solution

  • Using Redux-Toolkit in this way, is there any benefit to memo-izing my callbacks and variables?

    • Using useCallback to memoize the changeDataFilterOption function

      There is no benefit to memoizing the changeDataFilterOption function since it is not passed down as a prop to another React component where its reference stability would be an issue. It is passed as a div element's onClick handler.

    • Using useMemo to memoize the itemList value

      There is a likely benefit here to memoizing the result of getListOfThings(data) only when the data reference updates. If getListOfThings was a heavy/costly function call memoizing previous results saves from recomputing values that we know would be the same since the input didn't change. This obviously assumes the useGetUserQuery is providing a stable fetched data reference, which I believe it does, only updating when endpoint runs and updates the query cache.

    General Rules of Thumb

    1. A good general rule of thumb for useCallback is that you'll want to memoize and provide stable callback functions if passing them down as props to other React components.

    2. A good general rule of thumb for useMemo is to only memoize values if

      • They are passed down as props to other React components so they are provided as stable references.
      • Computationally "expensive" to compute.