Frontend Development

React useMemo and useCallback differences With Examples

React useMemo and useCallback differences With Examples

When talking about optimizing your react app, you probably heard about the useMemo() and useCallback() hooks in React.

 

 

Let’s walk through real-world examples of useMemo and useCallback in React, showing when and why you’d use them to improve performance and avoid unnecessary re-renders.

 

useMemo – Memoizing Expensive Computations

Avoid recalculating a derived value that’s computationally expensive unless its dependencies change.

Example: Filtering a Large List

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

const ProductList = ({ products }) => {
  const [search, setSearch] = useState('');

  // Expensive filtering operation
  const filteredProducts = useMemo(() => {
    console.log('Filtering products...');
    return products.filter(product =>
      product.name.toLowerCase().includes(search.toLowerCase())
    );
  }, [search, products]);

  return (
    <div>
      <input
        type="text"
        placeholder="Search products"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
      />
      <ul>
        {filteredProducts.map(product => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>
    </div>
  );
};

In this code we wrapped the logic that handles product filtering with useMemo(). In this case the search result is cached when searching with a previous search term. useMemo() accepts a callback and array of dependencies. When any of these dependencies change the useMemo() recalculates.

When to use useMemo:

  • Prevents filtering the list every render unless search or products change.

  • Speeds up rendering when working with large datasets.

 

useCallback – Memoizing Functions

Prevent passing new function instances to child components unless dependencies change.

Example: Avoid unnecessary Re-renders in Child Components

import React, { useState, useCallback } from 'react';

const Button = React.memo(({ onClick, label }) => {
  console.log(`Rendering button: ${label}`);
  return <button onClick={onClick}>{label}</button>;
});

const Counter = () => {
  const [count, setCount] = useState(0);
  const [other, setOther] = useState(0);

  // Memoize increment function
  const increment = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <Button onClick={increment} label="Increment" />
      <button onClick={() => setOther(prev => prev + 1)}>Update Other State</button>
    </div>
  );
};

When to use useCallback:

  • Without useCallback, the increment function would be re-created on every render.

  • React.memo would see a new prop function each time, causing unnecessary re-renders of Button.

 

Hook Purpose When to Use
useMemo Memoize values Expensive calculations, large filtered or sorted arrays
useCallback Memoize functions Prevent re-renders in memoized child components

 

0 0 votes
Article Rating

What's your reaction?

Excited
0
Happy
0
Not Sure
0
Confused
0

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments