React Memo

React.memois a Higher Order Component (HOC) used to optimize the performance of function components. It improves performance by memoizing the component's rendering output and skipping re-renders when the component's props have not changed. The following isReact.memothe detailed introduction and usage methods.

1. Basic Usage

React.memoThe basic usage is to pass a function component as an argument toReact.memo, and return a memoized component.

Example

import React from 'react';
import ReactDOM from 'react-dom';

const MyComponent = React.memo((props) => {
  console.log('Rendering MyComponent');
  return <div>{props.text}</div>;
});

const App = () => {
  const [count, setCount] = React.useState(0);
  const [text, setText] = React.useState('Hello, world!');

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <MyComponent text={text} />
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

In this example, even ifcountthe state changes,MyComponentit will not re-render, because itspropshas not changed.

2. Using a Custom Comparison Function

By default,React.memoonly compares the previous and nextprops, and if there is no change, it will not re-render. You can control the re-rendering logic more precisely by passing a custom comparison function.

Signature of the custom comparison function:

function areEqual(prevProps, nextProps) {
  // 返回 true 表示相等,不需要重新渲染
  // 返回 false 表示不相等,需要重新渲染
}

Example

import React from 'react';
import ReactDOM from 'react-dom';

const MyComponent = React.memo((props) => {
  console.log('Rendering MyComponent');
  return <div>{props.text}</div>;
}, (prevProps, nextProps) => {
  return prevProps.text === nextProps.text;
});

const App = () => {
  const [count, setCount] = React.useState(0);
  const [text, setText] = React.useState('Hello, world!');

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <MyComponent text={text} />
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

In this example, the custom comparison function checkstextwhether it has changed. Iftexthas not changed,MyComponentit will not re-render.

3. Practical Application Scenarios

React.memoIt is very suitable for the following scenarios:

  • Static data display: the props received by the componentpropsrarely change, but the component itself is relatively complex, and re-rendering is costly.
  • Performance optimization: In large lists or tables, each item is an independent component, usingReact.memocan avoid unnecessary re-renders.
  • Avoid deep equality checks: the custom comparison function can avoid deep equality checks, especially whenpropscontains a large amount of data.

4. Notes

  • Shallow comparison: By default,React.memoperforms a shallow comparison, meaning it only comparespropsthe top-level content. Nested objects require a custom comparison function.
  • State and context:React.memoonly focuses onpropschanges. Changes in the component's internal state and context will not trigger re-rendering.

5. WithuseMemoanduseCallbackthe difference

  • React.memo: used to memoize the entire component and optimize component rendering.
  • useMemo: used to memoize values or computed results inside function components.
  • useCallback: used to memoize callback functions inside function components to avoid unnecessary re-creation.

Example

import React, { useState, useMemo, useCallback } from 'react';
import ReactDOM from 'react-dom';

const ChildComponent = React.memo(({ onClick, count }) => {
  console.log('Rendering ChildComponent');
  return <button onClick={onClick}>Count: {count}</button>;
});

const App = () => {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  const doubledCount = useMemo(() => count * 2, [count]);

  return (
    <div>
      <p>Doubled Count: {doubledCount}</p>
      <ChildComponent onClick={increment} count={count} />
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

In this example,useCallbackanduseMemois used to optimize functions and computed results,React.memois used to optimize the rendering of child components.

Summary

React.memois a powerful tool that can effectively improve the performance of function components and avoid unnecessary re-renders. By usingReact.memoand custom comparison functions, you can significantly optimize application performance without affecting application logic.

Other extensions