ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку

Динамическая высота элемента в React после рендера

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для выполнения кода после рендера в React вам понадобится использовать хук useEffect:

JS
Скопировать код
import React, { useEffect } from 'react';

const MyComponent = () => {
  useEffect(() => {
    console.log('Мы встретились после рендера!');
  }, []); // Срабатывает однократно после монтирования

  return <div>Я здесь!</div>;
};

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

Пройдите тест и узнайте подходит ли вам сфера IT
Пройти тест

Использование методов жизненного цикла для задач «после рендера» в классовых компонентах

В классовых компонентах для задач, выполняемых после первого рендеринга, используют метод componentDidMount:

JS
Скопировать код
componentDidMount() {
  const div = ReactDOM.findDOMNode(this);
  div.style.height = `${window.innerHeight}px`; // Мы устанавливаем div высоту, соответствующую высоте окна. Ничего себе, да?
}

Синхронные операции и измерение макета с useLayoutEffect

Для функциональных компонентов существует хук useLayoutEffect. Если требуется провести измерения или получить мгновенный эффект до рендеринга браузером, то useLayoutEffect будет как нельзя кстати:

JS
Скопировать код
useLayoutEffect(() => {
  const node = ref.current;
  node.style.height = `${node.scrollHeight}px`; // Знаете ли вы, что высота – это лишь вопрос восприятия?
}, []);

Оптимизация производительности с requestAnimationFrame

Внутри useEffect или useLayoutEffect можно использовать requestAnimationFrame для синхронизации измерительных операций и изменений DOM с последующим циклом рендеринга браузера. Это поможет избежать ненужной перекомпоновки и перерисовки, улучшив тем самым производительность:

JS
Скопировать код
useEffect(() => {
  requestAnimationFrame(() => {
    // Впечатляет этот уровень оптимизации, не так ли?
  });
});

Адаптация к изменениям с componentDidUpdate

В классовых компонентах метод componentDidUpdate адаптируется к изменениям. В нём можно вносить корректировки размеров элемента, например, в ответ на изменение размера окна:

JS
Скопировать код
componentDidUpdate(prevProps, prevState) {
  if (prevState.windowWidth !== this.state.windowWidth) {
    this.adjustHeight(); // Неважно какой размер у окна, я всегда в хорошем расположении духа!
  }
}

Управление видимостью и предотвращение мерцания

Для устранения эффекта мерцания или прыжков макета, вы можете изначально сделать элементы невидимыми, а затем показать их после рендеринга:

JS
Скопировать код
state = {
  isContentLoaded: false,
};

componentDidMount() {
  this.setState({ isContentLoaded: true }); // Настало время появление на сцене!
}

А на основе этого состояния – менять стили в методе render компонента:

JS
Скопировать код
render() {
  return (
    <div style={{ visibility: this.state.isContentLoaded ? 'visible' : 'hidden' }}>
      { /* Когда данные загружены, начинается спасский танец! */ }
    </div>
  );
}

Визуализация

Процесс рендеринга в React можно представить как поездку на поезде:

🚂💨: [🚉 Установка компонента]

🔁: [🛤️ Цикл обновлений]

🚉🏁: После рендера [ useEffect(() => { ... }, []) ]

Здесь важнее путь, а не конечная точка. Хук useEffect с пустым массивом зависимостей [] срабатывает один раз, после монтирования.

До: [🧳 Багаж (состояние) еще не распакован]

После: [🏨 Багаж распаковали в номере отеля (в DOM)]

Снижение влияния побочных эффектов с помощью callback-ов

Иногда требуется изменить состояние или выполнить дополнительные вычисления после рендера. Метод setState в React может принимать callback-функцию:

JS
Скопировать код
this.setState({
  dynamicHeight: window.innerHeight,
}, () => {
  // После обновления состояния у нас есть возможность заняться вычислениями. Ведь кто сказал, что после работы нельзя повеселиться?
});

Прямой доступ к DOM через refs

Refs позволяют напрямую обращаться к DOM-элементам или элементам рендеринга React. Используя refs после рендера, можно получать значения, например, высоту элемента при прокрутке:

JS
Скопировать код
const myRef = useRef(null);

useEffect(() => {
  const node = myRef.current;
  console.log(node.scrollHeight); // Как высоко мы поднялись, посмотрите-ка!
}, []);

Полезные материалы

  1. React.Component – React — Объяснение методов жизненного цикла, таких как componentDidMount.
  2. Использование хука Effect – React — Ознакомление с использованием хука useEffect для создания побочных эффектов в функциональных компонентах.
  3. Компоненты высшего порядка – React — Глубокое погружение в использование переиспользуемых компонентов с помощью паттерна HOC.
  4. Состояние и жизненный цикл – React — Обзорная информация о состоянии и жизненном цикле в классовых компонентах.
  5. Как получить данные с помощью React Hooks — О том, как проводить асинхронные операции c useEffect в приложениях на React.