Optimize React Functional Components with React.memo

As a React developer, I’ve seen firsthand how performance bottlenecks can creep into even the simplest applications. One common culprit? Unnecessary re-renders of functional components. If you’re building React apps for clients in the USA or anywhere else, optimising your components can drastically improve user experience.

In this article, I’ll walk you through how to use React.memo to optimise your functional components. I’ll share practical examples and explain the concepts clearly so you can apply them right away.

What is React.memo and Why Should You Use It?

React.memo is a higher-order component that memoises your functional component. In simple terms, it remembers the last rendered output and skips re-rendering the component if the props haven’t changed.

Think of it as a performance booster. When you wrap a component with React.memo, React compares the current props with the previous ones. If they are the same, React reuses the last rendered result instead of rendering the component again.

This is especially useful in apps where components receive props that don’t change often, but parent components re-render frequently, a common scenario in real-world USA-based projects with dynamic UIs.

How React.memo Works: A Simple Example

Let me show you a basic example. Imagine you have a component that displays a user’s name. Without React.memo, every time the parent re-renders, this component re-renders too, even if the name didn’t change.

Here’s the code without React.memo:

import React, { useState } from 'react';

function UserName({ name }) {
  console.log('UserName rendered');
  return <h2>User: {name}</h2>;
}

function App() {
  const [count, setCount] = useState(0);
  const userName = 'John Doe';

  return (
    <div>
      <UserName name={userName} />
      <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>
    </div>
  );
}

export default App;

You can see the output in the screenshot below.

Optimize React Functional Components with React.memo

If you run this and click the button, you’ll see “UserName rendered” logged every time — even though the userName prop never changes.

Add React.memo to Prevent Unnecessary Re-renders

Now, let’s optimise the UserName component using React.memo:

import React, { useState } from 'react';

const UserName = React.memo(function UserName({ name }) {
  console.log('UserName rendered');
  return <h2>User: {name}</h2>;
});

function App() {
  const [count, setCount] = useState(0);
  const userName = 'John Doe';

  return (
    <div>
      <UserName name={userName} />
      <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>
    </div>
  );
}

export default App;

Now, when you click the button, the parent component (App) re-renders, but UserName does not re-render because its props haven’t changed.

This simple change can save a lot of processing time in larger applications, especially when components are complex or render large subtrees.

When to Use React.memo: Practical Tips

From my experience, here are some practical guidelines:

  • Use React.memo when your component is pure and renders the same output for the same props.
  • It’s ideal for components that receive primitive props (strings, numbers, booleans).
  • If your props are objects or arrays, React.memo does a shallow comparison by default, which might not catch big changes.
  • For complex props, you can provide a custom comparison function to React.memo.

Use a Custom Comparison Function

Sometimes, your props might be objects or arrays, and you want React.memo to re-render only when specific properties change. Here’s how you can do that:

import React, { useState } from 'react';

const UserProfile = React.memo(
  function UserProfile({ user }) {
    console.log('UserProfile rendered');
    return (
      <div>
        <h3>{user.name}</h3>
        <p>Age: {user.age}</p>
      </div>
    );
  },
  (prevProps, nextProps) => {
    // Only re-render if user.name changes
    return prevProps.user.name === nextProps.user.name;
  }
);

function App() {
  const [count, setCount] = useState(0);
  const user = { name: 'Jane Smith', age: 30 };

  return (
    <div>
      <UserProfile user={user} />
      <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>
    </div>
  );
}

export default App;

You can see the output in the screenshot below.

React Functional Components with React.memo

In this example, UserProfile will only re-render if the name property of the user object changes. Changes to age or other props won’t trigger a re-render.

React.memo vs useMemo and useCallback: What’s the Difference?

You might wonder how React.memo compares to useMemo and useCallback. Here’s a quick rundown:

  • React.memo memoises the component rendering result.
  • useMemo memoises the result of a function inside a component.
  • useCallback memoises a function instance to prevent unnecessary re-creation.

In practice, you often use them together for optimal performance. For example, memoise expensive calculations with useMemo and memoise callbacks with useCallback to avoid triggering re-renders in memoised components.

Real-World Example: Optimising a USA-based Employee List

Let me share a practical example that might resonate with you if you’re building an employee management dashboard for a company in the USA.

Imagine you have a list of employees with their names and departments. The app frequently updates other parts of the UI, but employee data changes rarely.

Here’s how you can optimise the employee row component:

import React, { useState } from 'react';

const EmployeeRow = React.memo(({ employee }) => {
  console.log(`Rendering ${employee.name}`);
  return (
    <div style={{ padding: '10px', borderBottom: '1px solid #ddd' }}>
      <strong>{employee.name}</strong> - {employee.department}
    </div>
  );
});

function EmployeeList() {
  const [clicks, setClicks] = useState(0);
  const employees = [
    { id: 1, name: 'Alice Johnson', department: 'Engineering' },
    { id: 2, name: 'Bob Smith', department: 'Marketing' },
    { id: 3, name: 'Carol White', department: 'Finance' },
  ];

  return (
    <div>
      <h1>Employees</h1>
      {employees.map(emp => (
        <EmployeeRow key={emp.id} employee={emp} />
      ))}
      <button onClick={() => setClicks(clicks + 1)}>Clicks: {clicks}</button>
    </div>
  );
}

export default EmployeeList;

You can see the output in the screenshot below.

Functional Components with React.memo

In this setup, clicking the button causes the parent EmployeeList to re-render, but thanks to React.memo, each EmployeeRow only renders once initially. This saves resources when your app scales to hundreds or thousands of employees.

Things to Watch Out For

  • Avoid overusing React.memo. Not every component benefits from memoisation.
  • Memoisation adds some overhead for prop comparison, so use it where performance gains outweigh this cost.
  • Beware of inline objects or functions passed as props; they create new references on every render and can cause memoisation to fail.
  • Use useCallback or useMemo to stabilise such props if needed.

I hope this guide helps you understand how to use React.memo to optimise functional components effectively. It’s an easy tool that can make a big difference in the performance of your React apps, especially for complex UIs or frequently updating parent components.

If you’re building applications for clients or users in the USA, where user experience and speed are critical, React.memo is definitely worth adding to your React toolkit.

You may also read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.