DevGang
Авторизоваться

Как предотвратить ненужную повторную отрисовку компонента React

Понимание того, как React Native отображает компоненты, необходимо для создания эффективных и производительных приложений. Когда состояние или свойства компонента изменяются, React автоматически обновляет пользовательский интерфейс (UI), чтобы отразить эти изменения. В результате React снова вызывает метод отображения компонента, чтобы сгенерировать обновленное представление UI.

В этой статье мы рассмотрим три React Hooks и то, как они предотвращают ненужные рендеринги в React:

  • useMemo
  • userCallback
  • userRef

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

К концу этой статьи мы лучше поймем, как сделать наши приложения React более быстрыми и отзывчивыми, используя эти удобные хуки React.

Использование useMemo в React

В React useMemo может предотвратить ненужные повторные рендеринги и оптимизировать производительность.

Давайте рассмотрим, как хук useMemo может предотвратить ненужные повторные рендеринги в наших компонентах React.

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

Рассмотрим следующий пример:

import { useMemo, useState } from 'react';

    function Page() {
      const [count, setCount] = useState(0);
      const [items] = useState(generateItems(300));

      const selectedItem = useMemo(() => items.find((item) => item.id === count), [
        count,
        items,
      ]);

      function generateItems(count) {
        const items = [];
        for (let i = 0; i < count; i++) {
          items.push({
            id: i,
            isSelected: i === count - 1,
          });
        }
        return items;
      }

      return (
        <div className="tutorial">
          <h1>Count: {count}</h1>
          <h1>Selected Item: {selectedItem?.id}</h1>
          <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
      );
    }

    export default Page;

Приведенный выше код представляет собой компонент React под названием Page, который использует useMemo для оптимизации вычисления selectedItem.

Вот объяснение:

  • Компонент поддерживает переменную состояния count c помощью хука useState.
  • Состояние элементов инициализируется с помощью хука useState с результатом функции generateItems.
  • selectedItem вычисляется с помощью useMemo, который запоминает результат операции items.find. Он пересчитывается только при изменении количества или самих элементов.
  • Функция generateItems генерирует массив элементов на основе заданного количества.
  • Компонент отображает текущее value счетчика, идентификатор selectedItem и кнопку для увеличения счетчика.

Использование useMemo оптимизирует производительность, запоминая результат операции items.find. Это гарантирует, что вычисление selectedItem выполняется только при изменении зависимостей (количества или элементов), предотвращая ненужные повторные вычисления при последующих рендерингах.

Мемоизацию следует применять выборочно для операций с интенсивными вычислениями, поскольку она вносит дополнительные накладные расходы в процесс рендеринга.

Использование useCallback в React

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

Рассмотрим следующий пример:

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

    const allColors = ['red', 'green', 'blue', 'yellow', 'orange'];

    const shuffle = (array) => {
      const shuffledArray = [...array];
      for (let i = shuffledArray.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]];
      }
      return shuffledArray;
    };

    const Filter = memo(({ onChange }) => {
      console.log('Filter rendered!');

      return (
        <input
          type='text'
          placeholder='Filter colors...'
          onChange={(e) => onChange(e.target.value)}
        />
      );
    });

    function Page() {
      const [colors, setColors] = useState(allColors);
      console.log(colors[0])

      const handleFilter = useCallback((text) => {
        const filteredColors = allColors.filter((color) =>
          color.includes(text.toLowerCase())
        );
        setColors(filteredColors);
      }, [colors]);


      return (
        <div className='tutorial'>
        <div className='align-center mb-2 flex'>
          <button onClick={() => setColors(shuffle(allColors))}>
            Shuffle
          </button>
          <Filter onChange={handleFilter} />
        </div>
        <ul>
          {colors.map((color) => (
            <li key={color}>{color}</li>
          ))}
        </ul>
      </div>
      );
    }

    export default Page;

Код выше демонстрирует простую цветовую фильтрацию и перемешивание в компоненте React. Давайте рассмотрим это шаг за шагом:

  • Начальный массив цветов определяется как allColors.
  • Функция shuffle берет массив и перемешивает его элементы случайным образом. Для перемешивания она использует алгоритм Фишера-Йетса.
  • Компонент Filter — это мемоизированный функциональный компонент, который визуализирует элемент ввода. Он получает свойство onChange и запускает функцию обратного вызова при изменении входного значения.
  • Компонент Page является основным компонентом, который обеспечивает функциональность фильтрации и перемешивания цветов.
  • Переменные состояния colors инициализируются с помощью хука useState, при этом начальное значение устанавливается как allColors. Он представляет собой отфильтрованный список цветов.
  • Функция handleFilter создается с помощью хука useCallback. Она принимает текстовый параметр и фильтрует массив allColors на основе предоставленного текста. Затем отфильтрованные цвета устанавливаются с помощью функции setColors из хука useState. Массив зависимостей [colors] гарантирует, что функция handleFilter будет создана заново только в случае изменения состояния цветов, что оптимизирует производительность, предотвращая ненужные повторные рендеринги.
  • Внутри компонента Page есть кнопка для перемешивания цветов. При нажатии на кнопку вызывается функция setColors с перемешанным массивом allColors.
  • Компонент Filter визуализируется с помощью свойства onChange, установленного на функцию handleFilter.
  • Наконец, массив цветов сопоставляется для отображения списка цветовых элементов.

Хук useCallback используется для запоминания функции handleFilter, что означает, что функция создается только один раз и повторно используется при последующих рендерингах, если зависимости (в данном случае состояние цветов) остаются прежними.

Эта оптимизация предотвращает ненужные повторные рендеры дочерних компонентов, которые получают функцию handleFilter как prop, например, компонента Filter.

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

Использование useRef в React

Другой подход к повышению производительности в приложениях React и предотвращению ненужных повторных рендеров — использование хука useRef. Используя useRef, мы можем хранить изменяемое значение, которое сохраняется между рендерами, эффективно предотвращая ненужные повторные рендеры.

Эта техника позволяет нам поддерживать ссылку на значение без запуска обновлений компонентов при изменении этого значения. Используя изменчивость ссылки, мы можем оптимизировать производительность в определенных сценариях.

Рассмотрим следующий пример:

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

function App() {
  const [name, setName] = useState('');
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        ref={inputRef}
      />
      <button onClick={handleClick}>Focus</button>
    </div>
  );
}

В примере выше есть простое поле ввода и кнопка. Хук useRef создает ссылку с именем inputRef. Как только нажимается кнопка, вызывается функция handleClick, которая фокусируется на элементе ввода, обращаясь к текущему свойству inputRef объекта ref. Таким образом, это предотвращает ненужную повторную визуализацию компонента при изменении входного значения.

Чтобы обеспечить оптимальное использование useRef, зарезервируйте его исключительно для изменяемых значений, которые не влияют на рендеринг компонента. Если изменяемое значение влияет на рендеринг компонента, его следует хранить в его состоянии.

Заключение

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

Источник:

#JavaScript #ReactNative
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу