React Memo

React.memoes un componente de orden superior (Higher Order Component, HOC) que se utiliza para optimizar el rendimiento de los componentes de función. Memoriza la salida de renderizado del componente y, cuando las props no han cambiado, omite el re-renderizado, mejorando así el rendimiento. A continuación se presentaReact.memola introducción detallada y el método de uso.

1. Uso básico

React.memoEl método de uso básico es pasar un componente de función como parámetro aReact.memo, y devuelve un componente memorizado.

Ejemplo

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 />);

En este ejemplo, incluso sicountel estado cambia,MyComponentno se volverá a renderizar, porque suspropsno han cambiado.

2. Uso de una función de comparación personalizada

Por defecto,React.memosolo compara lasprops, si no hay cambios, no se volverá a renderizar. Puedes controlar con mayor precisión la lógica de re-renderizado pasando una función de comparación personalizada.

Firma de la función de comparación personalizada:

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

Ejemplo

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 />);

En este ejemplo, la función de comparación personalizada verificatextsi ha cambiado. Sitextno ha cambiado,MyComponentno se volverá a renderizar.

3. Escenarios de aplicación práctica

React.memoEs muy adecuado para los siguientes escenarios:

  • Visualización de datos estáticos: las que recibe el componentepropscambian muy pocas veces, pero el componente en sí es relativamente complejo y el costo de re-renderizado es alto.
  • Optimización del rendimiento: en listas o tablas grandes, cada elemento es un componente independiente; el uso deReact.memopuede evitar re-renderizados innecesarios.
  • Evitar la comprobación de igualdad profunda: la función de comparación personalizada puede evitar la comprobación de igualdad profunda, especialmente cuandopropscontiene una gran cantidad de datos.

4. Notas importantes

  • Comparación superficial: por defecto,React.memorealiza una comparación superficial, lo que significa que solo comparapropsel contenido de primer nivel; los objetos anidados requieren una función de comparación personalizada.
  • Estado y contexto:React.memoSolo se enfoca enpropslos cambios de; los cambios en el estado y el contexto internos del componente no provocan un re-renderizado.

5. Comparación conuseMemoyuseCallbackdiferencias

  • React.memo: se utiliza para memorizar el componente completo, optimizando el renderizado del componente.
  • useMemo: se utiliza para memorizar valores o resultados de cálculo dentro de los componentes de función.
  • useCallback: se utiliza para memorizar las funciones de devolución de llamada dentro de los componentes de función, evitando recreaciones innecesarias.

Ejemplo

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 />);

En este ejemplo,useCallbackyuseMemose utiliza para optimizar funciones y resultados de cálculo,React.memose utiliza para optimizar el renderizado de subcomponentes.

Resumen

React.memoes una herramienta poderosa que puede mejorar eficazmente el rendimiento de los componentes de función y evitar re-renderizados innecesarios. Mediante el uso razonable deReact.memoy funciones de comparación personalizadas, puedes optimizar significativamente el rendimiento de la aplicación sin afectar la lógica de la aplicación.

Otras extensiones