November 21, 2022

React useMemo Hook With Examples

In the post React.memo With Examples we have seen how you can use it to memoize a whole component in order to avoid unnecessary re-renderings and have some performance gain. On the same lines you can use useMemo hook in React to memoize a computed value so that same cached value can be used in subsequent re-renderings. That way you can avoid unnecessary computations during re-renders and have some performance gain.

How does useMemo hook work

useMemo Hook lets you cache the result of a calculation between component re-renders.

Syntax of useMemo hook in React is as given below-

useMemo(calculateValue, dependencies)

Parameters

  • calculateValue: It is the function which calculates the value that you want to memoize. It should be a pure function, should take no arguments, and should return a value of any type.
  • dependencies: The list of all values referenced inside the calculateValue function. These reactive values include props, state, and all the variables and functions declared directly inside your component body.

React will call your function during the initial render and return the result of calling calculateValue.

On subsequent renders, React will return an already stored value from the last render if the dependencies have not changed. For that React will compare the dependencies with the dependencies you passed during the last render.

Otherwise, it will call calculateValue, return its result, and store it in case it can be reused later.

useMemo() React example

In this example we'll have a component Child.js where we have a function computeExpensiveValue that has a for loop which runs 1000000 times to simulate an extensive computation.

We are also managing two states; count (used in computeExpensiveValue function) and isDarkMode (for theme, which is not used in computeExpensiveValue function).

Since any state change triggers re-rendering so computeExpensiveValue function will also run whenever state changes for either count or theme. Since computeExpensiveValue function has a dependency on count so it should run again for count state change but it has no dependency on theme state change still the function with its loop runs for that also when the component re-renders.

App.js

import Child from './components/MemoDemo/Child';

function App() {
  const [isDarkMode, setIsDarkMode] = useState(0);
  const [count, setCount] = useState(0);
  const increment = () => {
    setCount(count + 1);
  };
  return (

    <>
      Count: {count}
      <button onClick={increment}>+</button>
      <br />

      <input
        type="checkbox"
        checked={isDarkMode}
        onChange={e => setIsDarkMode(e.target.checked)}
      />
      Dark mode

      <hr />
      <Child count={count} theme={isDarkMode? 'dark-mode' : 'light-mode'}/>
  );
}

export default App;

Child.js

import './theme.css';
const Child = (props) => {
    const computeExpensiveValue = () => {
        console.log('In computeExpensiveValue function');
        let num = props.count;
        for(let i = 0; i < 1000000; i++){
            num += 1;
        }
        return num;
    };
    return(
        <div className={props.theme}>
            <h2>Expensive Calculation</h2>
            {computeExpensiveValue()}
        </div>
    );
}

export default Child;

theme.css

.dark-mode {
    background-color: black;
    color: white;
}
.light-mode {
    background-color: white;
    color: black;
}
React useMemo Hook

As you can see log in the function is displayed for both count and theme state changes.

Wrapping the computeExpensiveValue() function with in the useMemo() hook and providing count as dependency ensures that the computed value of the function is memoized. When the count state changes, function will run again because of the dependency but the cached value will be returned when the theme state changes.

import { useMemo } from 'react';
import './theme.css';
const Child = (props) => {
    const computeExpensiveValue = useMemo(() => {
        console.log('In computeExpensiveValue function');
        let num = props.count;
        for(let i = 0; i < 1000000; i++){
            num += 1;
        }
        return num;
    }, [props.count]);
    return(
        <div className={props.theme}>
            <h2>Expensive Calculation</h2>
            {computeExpensiveValue}
        </div>
    );
}

export default Child;

Now change in theme state doesn't result in the computeExpensiveValue() function execution. Note that Child component is still re-rendered only thing that is cached is the value of the function because of the use of useMemo hook.

That's all for the topic React useMemo Hook With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment