Voltron Studio logo black rectangle

Article

React Hooks: Why your React app is running into memory problems and how useMemo hook can help

Dennis Tang

·4 mins read

React continues to evolve and provide APIs to help developers fine-tune and optimize their web applications. In this article, we look at how, when, and why you should be using React.useMemo in your frontend application code.

What is memoization?

Memoization is an optimization technique that passes a complex function to be memoized or remembered. The results from the previous computation is remembered and future invocations using the same arguments are cached and looked up.

React.useMemo optimizes your components, avoiding complex re-rendering when it isn’t required. In this article, we look at how we can apply this hook to help optimize our React application incrementally.

Show me the code

Before we write up some code let’s establish some assumptions to provide more context on the examples below.

  • Assumption 1: getFilteredData is a memory-intensive computation
  • Assumption 2: configs prop changes quite frequently
  • Assumption 3: Chart is always mounted on the UI
  • Assumption 4: rawData is a large and deeply nested prop
const Chart = ({ rawData, filters, configs }) => {
  const filteredData = getFilteredData(rawData, filters);
  return <ComplexGraph data={filteredData} />;
}

Here we are wrapping useMemo around getFilterData and we pass in rawData and filters as dependencies in the second argument. Here we're wrapping getFilter with useMemo passing in rawData and filters as dependencies. These dependencies tell useMemo to only recompute getFilterData if they change. Dependency array should only be watching for props your computation method uses to return its value.

const Chart = ({ rawData, filters, configs }) => {
  const filteredData = React.useMemo(() =>
      getFilteredData(rawData, filters),
      [rawData, filters],
  );
  return <ComplexGraph data={filteredData} />;
}

Here we are wrapping useMemo around getFilterData and we pass in the dependencies array as our second argument. Dependency array is a collection of props that useMemo can shallow compare against any diffs before computing your expensive value. Dependency array should only be watching for props your computation method uses to return its value.

  • Fact 1: Should configs prop change, getFilteredData does not re-compute, instead it will return the memoized value from its last invocation
  • Fact 2: Should rawData or filters prop change, getFilterData will re-compute and store the new return value for memoization
  • Fact 3: Should you unmount and re-mount the Chart component, getFilteredData will compute your expensive value again

The advantage is quite clear, we can easily begin to prevent our applications from computing values or rendering components that deal with large datasets or that chew up memory.

Use with caution

  • Don’t get carried away, use with caution as this is a performance optimization not a silver bullet to solve all your performance woes
  • Use useMemo when you have to a large dataset that requires regular updates
  • Medium to large size components that require expensive computed data

Keep in mind

  • useMemo does a shallow comparison on your dependency array
  • Only works for functional components
  • Don’t use useMemo to fire off any side effects or any asynchronous calls, instead use useEffect for that sort of logic
  • useCallback hook is similar to useMemo, but it returns a memoized function, while useMemo has a function that returns a value
  • Never pass in an empty dependency array to useMemo, it will just re-compute the value on every re-render

Conclusion

React memo is a great hook to help optimize computing large lists of complex components. Use it wisely and of course use a performance profiler to measure your gains.

Related tags
Software developmentReact
Written by

Dennis Tang

Co-Founder & Director at Voltron Studio

Sign up for our newsletter.

Be notified when we share new ideas and updates. Stay up-to-date on news and tips in web technologies, healthcare software, and radiology!

We care about the protection of your data. Read our privacy policy.

Voltron Studio logo white text and square

© 2021 Voltron Studio Pty Ltd, ABN 72 645 265 103