Как инженеры-программисты, одной из наших главных забот является производительность наших приложений. При создании приложения React оптимизация производительности может быть достигнута за счет использования двух мощных хуков: React.memo и useCallback.

React.memo — это оптимизация производительности, которая позволяет запоминать результат рендеринга компонента. Если компонент получает те же реквизиты, что и раньше, React будет повторно использовать ранее обработанный результат, а не отображать его снова. Мы можем использовать функцию memo() для переноса компонента следующим образом:

import React, { memo } from 'react';

const MyComponent = memo(props => {
  // Component code here
});

Запоминая результат рендеринга компонента, мы можем значительно повысить производительность нашего приложения, особенно при работе со сложными компонентами или большими списками.

Важно отметить, что React.memo выполняет только поверхностное сравнение свойств. Это означает, что если наши реквизиты являются сложными объектами или массивами, нам необходимо обеспечить их правильное сравнение, чтобы избежать ненужного повторного рендеринга. Мы можем добиться этого, реализовав пользовательскую функцию сравнения и передав ее в качестве второго аргумента функции memo().

Хук useCallback — это еще одна оптимизация производительности, которую можно использовать для запоминания функций. Запоминая функцию, мы можем избежать ненужного повторного рендеринга дочерних компонентов, которые полагаются на эту функцию. Мы можем определить нашу функцию и обернуть ее в useCallback() следующим образом:

import React, { useCallback } from 'react';

const MyComponent = props => {
  const handleClick = useCallback(() => {
    // Function code here
  }, []);

  return (
    <button onClick={handleClick}>Click me!</button>
  );
};

Если MyComponent выполняет повторный рендеринг, функция handleClick по-прежнему будет иметь ту же ссылку, поэтому любые дочерние компоненты, которые полагаются на нее, не будут повторно рендериться без необходимости. Нам нужно передать все зависимости нашей функции в качестве второго аргумента в useCallback(), чтобы наша мемоизация была максимально точной.

Теперь давайте посмотрим на рефакторинг компонента:

import React from 'react';

const MyComponent = ({ data }) => {
  const handleClick = () => {
    // Function code here
  };

  return (
    <div>
      <button onClick={handleClick}>Click me!</button>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
};

В этом примере компонент отображает список элементов, переданных в качестве реквизита, с помощью функции map(). Всякий раз, когда компонент перерисовывается, функция map() будет вызываться снова, даже если данные, переданные в качестве реквизита, не изменились. Это может привести к ненужным повторным рендерингам и повлиять на производительность приложения.

Мы можем оптимизировать этот компонент с помощью React.memo и useCallback следующим образом:

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

const ListItem = memo(({ item }) => {
  return <li key={item.id}>{item.name}</li>;
});

const MyComponent = memo(({ data }) => {
  const handleClick = useCallback(() => {
    // Function code here
  }, []);

  return (
    <div>
      <button onClick={handleClick}>Click me!</button>
      <ul>
        {data.map(item => (
          <ListItem key={item.id} item={item} />
        ))}
      </ul>
    </div>
  );
});

В этом оптимизированном компоненте мы разделили элементы списка на отдельный компонент ListItem и обернули его React.memo. Это гарантирует, что компонент будет повторно отображаться только в том случае, если его свойства изменились. Мы также запомнили функцию handleClick с помощью useCallback, чтобы предотвратить ненужную повторную визуализацию дочерних компонентов, которые полагаются на нее.

Оптимизируя наш компонент с помощью React.memo и useCallback, мы можем уменьшить количество ненужных повторных рендеров и повысить производительность нашего приложения React.

Таким образом, React.memo и useCallback — это мощные хуки, которые можно использовать для оптимизации рендеринга наших компонентов и повышения производительности наших приложений React. Запоминая результат рендеринга компонентов и функций, мы можем сократить количество ненужных повторных рендерингов и повысить общую эффективность нашего кода. Инженерам-программистам важно учитывать эти оптимизации производительности при создании приложений React, чтобы обеспечить лучший пользовательский интерфейс.