React: перерисовка компонентов при изменении размера окна
Быстрый ответ
Для отслеживания изменений размеров окна браузера и эффективной перерисовки компонентов React, создайте обработчик события resize
и примените хуки useState
и useEffect
для обновления состояния. Вот пример быстрого решения:
import { useState, useEffect } from 'react';
const useWindowSize = () => {
const [size, setSize] = useState([window.innerWidth, window.innerHeight]);
useEffect(() => {
const resizeHandler = () => setSize([window.innerWidth, window.innerHeight]);
window.addEventListener('resize', resizeHandler);
return () => window.removeEventListener('resize', resizeHandler);
}, []);
return size;
};
function MyResponsiveComponent() {
const [width, height] = useWindowSize();
return <div>Ширина: {width}, Высота: {height}</div>;
}
Созданный нами хук useWindowSize
инкапсулирует необходимую логику, упрощая тем самым отображение текущих размеров окна компонентами.
Ускорение работы с помощью метода отсечения вызовов
Используйте метод отсечения вызовов (debouncing) для улучшения производительности. Он позволяет уменьшить количество перерисовок при изменении размера окна, выполняя обновление состояния только после полного завершения серии изменений:
import { useState, useEffect } from 'react';
import debounce from 'lodash.debounce';
const useWindowSize = () => {
const [size, setSize] = useState([window.innerWidth, window.innerHeight]);
useEffect(() => {
const debouncedResizeHandler = debounce(() => {
setSize([window.innerWidth, window.innerHeight]);
}, 100);
window.addEventListener('resize', debouncedResizeHandler);
return () => {
debouncedResizeHandler.cancel();
window.removeEventListener('resize', debouncedResizeHandler);
};
}, []);
return size;
};
Применение отсечения вызовов поможет заметно улучшить производительность.
Следование принципу DRY с помощью пользовательских хуков
Использование пользовательских хуков для отслеживания изменений размера окна обеспечивает чистоту кода и его приятное для восприятия внешнее вид. Переиспользуйте хуки для улучшения структуры кода.
// useWindowSize.js
import { useState, useEffect } from 'react';
export default function useWindowSize(){
// ...тот же код, что и выше...
}
// MyResponsiveComponent.js
import useWindowSize from './useWindowSize';
function MyResponsiveComponent() {
// ...используйте наш пользовательский хук...
}
Соблюдение принципа DRY упрощает поддержку кода.
Сохранение контекста при помощи стрелочных функций
Стрелочные функции помогут сохранить контекст this
, когда вы создаёте обработчики событий, избавляя вас от необходимости применять bind
:
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
handleResize = () => {
// 'this' корректно привязано, проблем с контекстом не возникнет.
};
Благодаря стрелочным функциям поведение this
всегда предсказуемо, а код становится более понятным.
Визуализация
Изобразим, как React-компонент реагирует на изменение размера окна браузера, воспользовавшись аналогией с эволюцией:
Окно браузера: 🌐 Стандартный размер ---> 🌐 Увеличенный размер
React Компонент: 🐱👤 ---> 🐱🚀
{класс и хук}
**Компонент-класс** с `componentDidUpdate`: 🚪🐱👤 → Изменился ли размер? → 🔄 → 🚪🐱🚀
**Функциональный компонент** с `useEffect` и `useState`: 🚪🐱👤 → Изменился ли размер? → 🪄 → 🚪🐱🚀
Так мы можем наглядно представить, как React-компоненты приспосабливаются к изменению размера окна.
Использование методов жизненного цикла React для компонентов-классов
При работе с классами реализуйте методы жизненного цикла для отслеживания изменений размера окна браузера:
class MyResponsiveClassComponent extends React.Component {
state = {
width: window.innerWidth,
height: window.innerHeight,
};
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
handleResize = () => {
this.setState({
width: window.innerWidth,
height: window.innerHeight,
});
};
render() {
return <div>Ширина: {this.state.width}, Высота: {this.state.height}</div>;
}
}
Так мы не только назначаем соответствующие обработчики, но также ухаживаем за ресурсом, освобождая его при размонтировании компонента.
Контроль за побочными эффектами при помощи useEffect
Хук useEffect
— отличное средство управления побочными эффектами и предотвращения утечек памяти:
useEffect(() => {
// ...настроить обработчик изменения размера...
return () => {
// Аккуратное очистка — залог успешной работы.
window.removeEventListener('resize', resizeHandler);
};
}, []);
Освобождение ресурсов вовремя помогает избежать проблем с производительностью и утечкой памяти.
Управление перерисовкой путём изменения состояния
Контролируйте перерисовку компонентов, изменяя их состояние. Используйте setState
или forceUpdate
для реагирования на изменение размеров окна:
this.setState({ width: window.innerWidth });
// или
this.forceUpdate();
Таким путём компонент будет обновлён и отреагирует на последние изменения размеров окна.
Получение данных о размере окна
Для получения текущих размеров окна, используйте свойства window.innerWidth
и window.innerHeight
:
const width = window.innerWidth;
const height = window.innerHeight;
Благодаря этому можно легко реализовать адаптивные решения.
Улучшение кода с помощью CSS-медиа запросов
Дополните логику JavaScript по обработке изменения размеров использованием CSS-медиа запросов. Рассмотрите возможность совместного использования CSS и React для создания максимально адаптивного интерфейса.
Соблюдение приоритета производительности
Не забывайте об учете производительности при обработке изменения размеров. Оптимизируйте работу, применяя метод отсечения вызовов или управление вызовами (throttling).
Полезные материалы
- Строим адаптивные макеты с помощью React Hooks – LogRocket Blog — глубокое погружение в процесс создания адаптивных макетов в React.
- Использование хука Effect – React — официальное руководство React по использованию хука
useEffect
. - Полное руководство по CSS-медиа запросам | CSS-Tricks — детальное изучение CSS-медиа запросов для адаптивного дизайна.
- Отсечение и управление вызовами в JavaScript — обзор техник оптимизации обработки событий изменения размера.
- useWindowSize React Hook – useHooks — пользовательский хук React для отслеживания изменений размера окна.
- Как использовать React.useMemo() — разъяснение применения хука
useMemo
для повышения производительности в React.