React Interview Reference

Back to home

useMemo Hook

The useMemo hook memoizes expensive calculations to optimize performance.

Basic Usage

useMemo returns a memoized value that only recalculates when dependencies change.

jsx
import { useMemo, useState } from 'react';

function ExpensiveCalculation({ list, filter }) {
  // Memoize the filtered list
  const filteredList = useMemo(() => {
    console.log('Filtering list...');
    return list.filter(item => item.includes(filter));
  }, [list, filter]); // Only recalculate when list or filter changes

  return (
    <ul>
      {filteredList.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

Preventing Expensive Recalculations

Use useMemo to avoid recalculating expensive values on every render.

jsx
import { useMemo, useState } from 'react';

function PrimeCalculator() {
  const [number, setNumber] = useState(1);
  const [dark, setDark] = useState(false);

  // Expensive calculation memoized
  const isPrime = useMemo(() => {
    console.log('Calculating if prime...');
    if (number <= 1) return false;
    if (number <= 3) return true;
    if (number % 2 === 0 || number % 3 === 0) return false;
    
    let i = 5;
    while (i * i <= number) {
      if (number % i === 0 || number % (i + 2) === 0) return false;
      i += 6;
    }
    return true;
  }, [number]); // Only recalculate when number changes

  const theme = {
    backgroundColor: dark ? '#333' : '#FFF',
    color: dark ? '#FFF' : '#333'
  };

  return (
    <div style={theme}>
      <input
        type="number"
        value={number}
        onChange={e => setNumber(parseInt(e.target.value))}
      />
      <div>{number} is {isPrime ? 'prime' : 'not prime'}</div>
      <button onClick={() => setDark(prevDark => !prevDark)}>
        Toggle theme
      </button>
    </div>
  );
}

Memoizing Objects

useMemo is useful for preventing unnecessary re-renders caused by object recreation.

jsx
import { useMemo, useState } from 'react';

function MemoizedObject({ onSubmit }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  // Memoize the user object to prevent unnecessary re-renders
  const user = useMemo(() => {
    return { name, email };
  }, [name, email]);

  return (
    <form onSubmit={() => onSubmit(user)}>
      <input
        value={name}
        onChange={e => setName(e.target.value)}
        placeholder="Name"
      />
      <input
        value={email}
        onChange={e => setEmail(e.target.value)}
        placeholder="Email"
      />
      <button type="submit">Submit</button>
    </form>
  );
}

useMemo vs. React.memo

useMemo memoizes values, while React.memo memoizes components.

jsx
import { useMemo } from 'react';
import React from 'react';

// useMemo example - memoizes a value
function Component({ a, b }) {
  // This memoizes the result of the calculation
  const result = useMemo(() => {
    return expensiveCalculation(a, b);
  }, [a, b]);

  return <div>{result}</div>;
}

// React.memo example - memoizes a component
const MemoizedComponent = React.memo(function Component({ a, b }) {
  // This component only re-renders if a or b changes
  const result = expensiveCalculation(a, b);

  return <div>{result}</div>;
});

Common Interview Questions

  • ?
    What is the difference between useMemo and useCallback?
  • ?
    When should you use useMemo?
  • ?
    What are the performance implications of useMemo?
  • ?
    How does useMemo help with referential equality?
  • ?
    What happens if you don't provide a dependency array to useMemo?