#React
🚩 Как работать с react-window и react-virtualized?
Виртуализация - это техника, при которой React рендерит только видимые элементы вместо всех 1000+ элементов сразу. Остальные элементы создаются по мере прокрутки.
🔴 React-window vs React-virtualized
React-window (~5KB):
- Легковесная, быстрая
- Базовый функционал
- Идеальна для мобильных приложений
React-virtualized (~30KB):
- Больше компонентов и функций
- Таблицы, автомасштабирование, динамическая загрузка
- Подходит для сложных UI
🔴 Ключевые моменты
1. Всегда применяйте `style` — он управляет позиционированием
2. Определите размеры:
- Фиксированные: FixedSizeList
- Переменные: VariableSizeList
3. Оптимизируйте компоненты строк — используйте React.memo
4. Установите `overscanCount` (обычно 1-5 элементов)
🔴 Когда что использовать
- React-window: для простых списков, мобильных приложений
- React-virtualized: для сложных таблиц, нестандартных UI
🔴 Важно помнить
- ОБЯЗАТЕЛЬНО передавать style в корневой элемент каждой строки
- Избегать тяжелых расчетов в рендерере элементов
- Кэшировать данные и функции
Виртуализация — обязательный инструмент для React-приложений с большими данными.
🔎 🔎 🔎 🔎 🔄
#️⃣ Вопрос
#️⃣ Новости
#️⃣ База вопросов
Виртуализация - это техника, при которой React рендерит только видимые элементы вместо всех 1000+ элементов сразу. Остальные элементы создаются по мере прокрутки.
React-window (~5KB):
- Легковесная, быстрая
- Базовый функционал
- Идеальна для мобильных приложений
React-virtualized (~30KB):
- Больше компонентов и функций
- Таблицы, автомасштабирование, динамическая загрузка
- Подходит для сложных UI
1. Всегда применяйте `style` — он управляет позиционированием
2. Определите размеры:
- Фиксированные: FixedSizeList
- Переменные: VariableSizeList
3. Оптимизируйте компоненты строк — используйте React.memo
4. Установите `overscanCount` (обычно 1-5 элементов)
- React-window: для простых списков, мобильных приложений
- React-virtualized: для сложных таблиц, нестандартных UI
- ОБЯЗАТЕЛЬНО передавать style в корневой элемент каждой строки
- Избегать тяжелых расчетов в рендерере элементов
- Кэшировать данные и функции
Виртуализация — обязательный инструмент для React-приложений с большими данными.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍3🔥2👎1
Forwarded from Reactify | Frontend Разработка
В админке типового приложения таблицы встречаются на каждом шагу: пользователи, товары, заказы, подписки. Дизайн у них обычно единообразный — различаются только данные, заголовки и возможные действия в ячейках.
Проблема:
Если делать отдельный компонент под каждую сущность (UsersTable, ProductsTable), получим дублирование кода. Если запихать всю логику в один компонент — он превратится в монстра с кучей if-else.
Решение:
Делаем единную таблицу, но гибкую. Вместо хардкода данных и столбцов, выносим рендеринг наружу.
Какие техники применяем?
Итог:
Одна таблица на все случаи, без дублирования, с возможностью кастомизации под любую сущность.
Если тема интересна, сделаю серию постов про другие типовые компоненты: модалки, фильтры, карточки. Как вам идея?
#react #solid #patterns
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍8🔥6
#React
🚩 Что такое компоненты-контейнеры в React Redux?
Компоненты-контейнеры в React Redux — это подход, разделяющий компоненты на две категории:
🔴 Контейнеры:
- Подключаются к хранилищу Redux
- Получают данные из глобального состояния
- Отправляют действия (actions)
- Передают данные презентационным компонентам
🔴 Презентационные компоненты:
- Не знают о Redux
- Получают данные через props
- Отвечают только за отображение
- Вызывают функции через props при взаимодействии
✅ Преимущества
- Чёткое разделение логики и представления
- Повторное использование презентационных компонентов
- Простота тестирования
- Лучшая организация кода
🖇️ Современный подход
В современном React с появлением хуков (`useSelector` и `useDispatch`) необходимость в отдельных контейнерах уменьшилась. Теперь компоненты могут напрямую подключаться к Redux, сохраняя при этом принцип разделения ответственности.
🔎 🔎 🔎 🔎 🔄
#️⃣ Вопрос
#️⃣ Новости
#️⃣ База вопросов
Компоненты-контейнеры в React Redux — это подход, разделяющий компоненты на две категории:
- Подключаются к хранилищу Redux
- Получают данные из глобального состояния
- Отправляют действия (actions)
- Передают данные презентационным компонентам
- Не знают о Redux
- Получают данные через props
- Отвечают только за отображение
- Вызывают функции через props при взаимодействии
- Чёткое разделение логики и представления
- Повторное использование презентационных компонентов
- Простота тестирования
- Лучшая организация кода
В современном React с появлением хуков (`useSelector` и `useDispatch`) необходимость в отдельных контейнерах уменьшилась. Теперь компоненты могут напрямую подключаться к Redux, сохраняя при этом принцип разделения ответственности.
Контейнеры знают как всё работает, презентационные компоненты знают как всё должно выглядеть
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
#React
🚩 Как управлять фокусом с помощью хука useRef в React?
Хук useRef в React предоставляет способ взаимодействия с DOM-элементами, позволяя сохранять ссылку на элемент между рендерами без перерисовки компонента.
Это особенно полезно для управления фокусом на элементах, что важно для улучшения доступности и взаимодействия с пользователем.
В этом примере мы:
1️⃣ Создаем реф с помощью useRef
2️⃣ Присваиваем его текстовому полю с помощью атрибута ref
✅ При нажатии на кнопку "Установить фокус" вызывается функция handleFocus, которая устанавливает фокус на текстовое поле
🔎 🔎 🔎 🔎 🔄
#️⃣ Вопрос
#️⃣ Новости
#️⃣ База вопросов
Хук useRef в React предоставляет способ взаимодействия с DOM-элементами, позволяя сохранять ссылку на элемент между рендерами без перерисовки компонента.
Это особенно полезно для управления фокусом на элементах, что важно для улучшения доступности и взаимодействия с пользователем.
function FocusInput() {
const inputRef = useRef(null); // Создаем реф
const handleFocus = () => {
inputRef.current.focus(); // Устанавливаем фокус на элемент
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Введите текст" />
<button onClick={handleFocus}>Установить фокус</button>
</div>
);
}
В этом примере мы:
Вы можете использовать useRef для управления фокусом не только на текстовых полях, но и на других элементах, таких как кнопки или контейнеры.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤2
Forwarded from Reactify | Frontend Разработка
UI Kit представляет собой систематизированную коллекцию интерфейсных компонентов, которая служит фундаментом для разработки приложений. В современных проектах наличие продуманного UI Kit перешло из категории рекомендаций в обязательное требование по нескольким ключевым причинам.
[Картинка 1: Пример Storybook]
UI Kit — это не просто коллекция кнопок и полей ввода. Это комплексная система, включающая:
- Базовые компоненты интерфейса (кнопки, формы, переключатели)
- Типографику и иерархию текста
- Цветовую палитру с семантическим значением цветов
- Систему отступов и размеров
- Состояния элементов (активное, неактивное, hover, focus)
[Картинка 2 и 3: Дизайн в Figma]
При создании компонентов для UI Kit необходимо придерживаться нескольких фундаментальных принципов
1. Семантическая корректность
Каждый компонент должен максимально точно отражать свою суть на уровне HTML-разметки. Кнопка — это <button> или <input type="button">, ссылка — <a>, поле ввода — <input> или <textarea>. Это важно не только для доступности (accessibility), но и для правильной работы в различных контекстах (например, в формах или при навигации).
2. Полнота свойств
Компонент должен поддерживать все стандартные HTML-атрибуты соответствующего элемента. Для кнопки это включает type (button, submit, reset), disabled, autofocus и другие.
3. Управляемость извне
Компонент не должен содержать внутреннюю логику состояния (где это возможно). Все состояния (активное, неактивное, загружающееся) должны управляться через пропсы. Это делает компонент предсказуемым и легко интегрируемым в любую архитектуру.
4. Принцип открытости/закрытости
Компонент должен быть закрыт для модификаций (его базовое поведение нельзя изменить), но открыт для расширения. На практике это означает:
- Возможность добавления классов через className
- Возможность передачи произвольных атрибутов
- Гибкость в контенте через children
5. Единый источник правды
Изменение компонента в UI Kit должно автоматически отражаться во всех местах его использования. Это требует тщательного проектирования API компонента на этапе создания, чтобы избежать необходимости "ветвления" логики в будущем.
Оптимальная структура для UI Kit в проекте выглядит следующим образом:
src/
ui/
Button/
Button.tsx # React-компонент
Button.stories.tsx # Документация в Storybook
Button.test.tsx # Тесты компонента
Button.module.css # Стили компонента
Input/ # Аналогичная структура для других компонентов
...
styles/
variables.css # CSS-переменные (цвета, отступы, шрифты)
typography.css # Типографика
animations.css # Анимации
global.css # Глобальные стили
Перед разработкой тщательно изучаем макеты и выделяем все варианты кнопок: Варианты по стилю, Размеры, Состояния, Дополнительные требования (иконки, текст).
[Картинка 4: Компонент Button]
При стилизации используем CSS-переменные из дизайн-системы, Для каждого варианта прописываем цвета для всех состояний.
[Картинка 5: CSS-переменные]
Создаем подробные TypeScript-интерфейсы: Объединение с нативными атрибутами button и a, Поддержка всех стандартных HTML-атрибутов, Четкое разделение кастомных и стандартных пропсов
[Картинка 6: Типизация кнопки]
Далее создаем сторисы для всех вариантов: Основной вид, Все состояния, Примеры с иконками, Вариант как ссылки
#ui #storybook #button #react
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤4🔥4
#React
Сегодня изучим Паттерн наблюдатель - включайте видео!
🔎 🔎 🔎 🔎 🔄
#️⃣ Видео
#️⃣ Новости
#️⃣ База вопросов
Сегодня изучим Паттерн наблюдатель - включайте видео!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2❤1👍1
#React
🚩 Что такое размонтирование компонентов в React?
Размонтирование компонента в React — это процесс удаления компонента из виртуального DOM и, в конечном итоге, из реального DOM браузера. Это может происходить по разным причинам:
1️⃣ Когда вызывается функция очистки в useEffect?
1. Когда компонент полностью удаляется из DOM
2. Перед повторным выполнением эффекта (если зависимости изменились)
3. Перед перерисовкой компонента с новыми пропсами или состоянием
2️⃣ Что нужно очищать?
- Таймеры (setTimeout, setInterval)
- Слушатели событий (addEventListener)
- WebSocket соединения
- Подписки на внешние источники данных (Firebase, Redux)
- Нативные привязки к API устройства
3️⃣ Что предотвращает очистка?
- Утечки памяти
- Неожиданные побочные эффекты
- Ошибки типа "Can't perform a React state update on an unmounted component"
- Снижение производительности приложения
Правильное управление жизненным циклом компонентов — один из ключевых аспектов разработки эффективных и надежных React-приложений.
🔎 🔎 🔎 🔎 🔄
#️⃣ Вопрос
#️⃣ Новости
#️⃣ База вопросов
Размонтирование компонента в React — это процесс удаления компонента из виртуального DOM и, в конечном итоге, из реального DOM браузера. Это может происходить по разным причинам:
- Изменение состояния родительского компонента
- Условная отрисовка
- Переход на другую страницу
- Прямое удаление компонента
1. Когда компонент полностью удаляется из DOM
2. Перед повторным выполнением эффекта (если зависимости изменились)
3. Перед перерисовкой компонента с новыми пропсами или состоянием
- Таймеры (setTimeout, setInterval)
- Слушатели событий (addEventListener)
- WebSocket соединения
- Подписки на внешние источники данных (Firebase, Redux)
- Нативные привязки к API устройства
- Утечки памяти
- Неожиданные побочные эффекты
- Ошибки типа "Can't perform a React state update on an unmounted component"
- Снижение производительности приложения
Правильное управление жизненным циклом компонентов — один из ключевых аспектов разработки эффективных и надежных React-приложений.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤4
#React
🚩 Как в функциональных компонентах подписаться на события?
1. DOM-события (resize, keydown) - это события браузера, которые происходят вне React. Например, когда пользователь изменяет размер окна или прокручивает страницу.
Как это работает:
1️⃣ useEffect запускается один раз при создании компонента
2️⃣ Мы подписываемся на событие resize
3️⃣ В cleanup функции (return) обязательно отписываемся, если не отписаться, то обработчик останется в памяти даже после удаления компонента
2. Кастомные события (WebSocket, библиотеки) - это события от внешних источников - сокеты, сторонние библиотеки, API.
Как это работает:
1️⃣ Подписываемся на событие от внешнего источника
2️⃣ Сохраняем функцию отписки (обычно библиотеки возвращают её)
3️⃣ В cleanup вызываем отписку
3. React-события (onClick, onSubmit)
Это обычные события элементов, которые React обрабатывает сам.
Как это работает:
1️⃣ Просто передаём функцию в проп элемента
2️⃣ React сам подпишется и отпишется от события
3️⃣ Никаких useEffect не нужно
❗️ DOM и кастомные события → используй
❗️ React-события → просто передавай функцию в проп
Частые ошибки:
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
1. DOM-события (resize, keydown) - это события браузера, которые происходят вне React. Например, когда пользователь изменяет размер окна или прокручивает страницу.
useEffect(() => {
const handleResize = () => console.log('Окно изменилось');
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
Как это работает:
2. Кастомные события (WebSocket, библиотеки) - это события от внешних источников - сокеты, сторонние библиотеки, API.
useEffect(() => {
const unsubscribe = eventSource.on('message', handleMessage);
return () => unsubscribe();
}, []);
Как это работает:
3. React-события (onClick, onSubmit)
Это обычные события элементов, которые React обрабатывает сам.
const handleClick = () => console.log('Нажато!');
return <button onClick={handleClick}>Кнопка</button>;
Как это работает:
useEffect
+ обязательно отписывайсяЧастые ошибки:
1. Забыл отписаться - память засоряется, могут быть баги
2. Отписался неправильно - передал другую функцию вместо той же самой
3. Использовал useEffect для React-событий - не нужно, React сам справится
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
#React
🚩 Можно ли обновить React-компонент без изменения state?
Да, и способов больше, чем кажется!
Основные методы:
🖇️ Через props — изменяем состояние в родительском компоненте, и дочерний автоматически обновится
🖇️ forceUpdate() — принудительный ререндер в классовых компонентах (но лучше избегать)
🖇️ useReducer — элегантный способ для функциональных компонентов
🖇️ Внешние хранилища — Redux, Context API, MobX обновят все подписанные компоненты
Важный момент:
Чтобы избежать лишних перерендеров, используй React.memo, useMemo и useCallback.
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Да, и способов больше, чем кажется!
Основные методы:
Важный момент:
Даже если дочернему компоненту не передаются props, он всё равно перерендерится при обновлении родителя! Это поведение React по умолчанию.
Чтобы избежать лишних перерендеров, используй React.memo, useMemo и useCallback.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
#React
🚩 Как работает useReducer и когда его использовать вместо useState или Redux?
useReducer принимает редюсер
Когда что использовать?
🟣 useState
- Простое состояние (флаги, счетчики)
- Одно значение или примитивы
🟣 useReducer
- Сложная структура состояния
- Формы с валидацией
- Много связанных изменений
- Логика обновления зависит от предыдущего состояния
🟣 Redux
- Глобальное состояние
- Много компонентов используют одни данные
- Нужны middleware
- Сложные side-эффекты
useReducer - золотая середина между простотой useState и мощью Redux
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
useReducer принимает редюсер
(state, action) => newState
и возвращает [state, dispatch]
function counterReducer(state, action) {
switch (action.type) {
case 'increment': return { count: state.count + 1 };
case 'decrement': return { count: state.count - 1 };
default: return state;
}
}
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
Когда что использовать?
- Простое состояние (флаги, счетчики)
- Одно значение или примитивы
- Сложная структура состояния
- Формы с валидацией
- Много связанных изменений
- Логика обновления зависит от предыдущего состояния
- Глобальное состояние
- Много компонентов используют одни данные
- Нужны middleware
- Сложные side-эффекты
- 1 поле → useState
- Несколько связанных полей → useReducer
- Данные нужны везде → Redux
useReducer - золотая середина между простотой useState и мощью Redux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
#React
Можно ли задавать рандомные key в React?
Технически да, но это крайне не рекомендуется!
1️⃣ Зачем вообще нужны key?
React использует key для отслеживания изменений в списках и понимания, какие элементы обновить, а какие переиспользовать.
2️⃣ Проблемы с рандомными key
🔴 Потеря состояния компонентов
При ререндере React увидит новые key и решит, что это новые элементы. Форма в списке? Её состояние сбросится!
🔴 Снижение производительности
React не сможет оптимизировать обновления, так как key меняются каждый раз.
3️⃣ Что использовать вместо рандомных key?
🔴 Лучший вариант — уникальные ID из данных
🔴 Хеши от содержимого — если нет ID
🔴 Индексы массива — только для статичных списков
Пример ошибки
Запомните: стабильные key = стабильная работа React!
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Можно ли задавать рандомные key в React?
Технически да, но это крайне не рекомендуется!
React использует key для отслеживания изменений в списках и понимания, какие элементы обновить, а какие переиспользовать.
При ререндере React увидит новые key и решит, что это новые элементы. Форма в списке? Её состояние сбросится!
React не сможет оптимизировать обновления, так как key меняются каждый раз.
Пример ошибки
// Плохо: состояние сбрасывается
{items.map(item => (
<input key={Math.random()} defaultValue={item.value} />
))}
// Правильно: key стабильны
{items.map(item => (
<input key={item.id} defaultValue={item.value} />
))}
Запомните: стабильные key = стабильная работа React!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2🔥2
#React
Как думаете, вы пишите понятный код? Предлагаю изучить 5 продвинутых паттернов React и прокачаться 💪🏻
🔎 🔎 🔎 🔎 🔄
#⃣ Видео
#⃣ Новости
#⃣ База вопросов
Как думаете, вы пишите понятный код? Предлагаю изучить 5 продвинутых паттернов React и прокачаться 💪🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2❤1
#React
🚩 Каким способом лучше всего получить доступ к нативному DOM-элементу из React-компонента?
В современном React есть два основных способа получить доступ к DOM-элементам. Разберем, когда использовать каждый.
1️⃣ useRef — основной способ
Стандартный подход для получения доступа к DOM-элементу. Ссылка сохраняется между рендерами:
2️⃣ Callback refs — для особых случаев
Используйте, когда нужно выполнить действие сразу при создании элемента:
🖇 Когда какой способ выбрать:
- useRef — 95% случаев, когда нужен доступ к DOM
- Callback refs — когда нужна логика при создании/удалении элемента или работа с динамическими списками
Основные правила:
- Refs только для DOM API (focus, scroll, измерения)
- Не изменяйте содержимое через refs — используйте state
- Не читайте ref.current во время рендера
✅ Правильное использование:
❌ Неправильное использование:
🔴 Почему так нельзя:
- React не знает об изменениях — может перезаписать ваши изменения
- Нарушается однонаправленный поток данных
- Сложно отлаживать и тестировать
- Может вызвать проблемы с производительностью
Правильно — через state:
Вывод: useRef — ваш основной выбор для доступа к DOM. Callback refs используйте только когда нужна особая логика при создании/удалении элемента.
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
В современном React есть два основных способа получить доступ к DOM-элементам. Разберем, когда использовать каждый.
Стандартный подход для получения доступа к DOM-элементу. Ссылка сохраняется между рендерами:
function MyComponent() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
return <input ref={inputRef} />;
}
Используйте, когда нужно выполнить действие сразу при создании элемента:
function MyComponent() {
const setInputRef = (element) => {
if (element) {
element.focus(); // Сразу фокусируем при создании
console.log('Элемент создан');
} else {
console.log('Элемент удален');
}
};
return <input ref={setInputRef} />;
}
- useRef — 95% случаев, когда нужен доступ к DOM
- Callback refs — когда нужна логика при создании/удалении элемента или работа с динамическими списками
Основные правила:
- Refs только для DOM API (focus, scroll, измерения)
- Не изменяйте содержимое через refs — используйте state
- Не читайте ref.current во время рендера
// Фокусировка, измерения, скролл
const inputRef = useRef(null);
const handleClick = () => inputRef.current.focus();
// Изменение контента — используйте state!
const divRef = useRef(null);
divRef.current.innerHTML = '<p>Текст</p>';
- React не знает об изменениях — может перезаписать ваши изменения
- Нарушается однонаправленный поток данных
- Сложно отлаживать и тестировать
- Может вызвать проблемы с производительностью
Правильно — через state:
const [content, setContent] = useState('');
return <div>{content}</div>;
Вывод: useRef — ваш основной выбор для доступа к DOM. Callback refs используйте только когда нужна особая логика при создании/удалении элемента.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1
#React
🚩 Что такое React и какие ключевые особенности он имеет?
React — это JavaScript-библиотека для создания пользовательских интерфейсов, разработанная Facebook. Она позволяет строить интерактивные веб-приложения с помощью компонентов.
1️⃣ Компонентная архитектура
React разбивает интерфейс на независимые компоненты, которые можно переиспользовать:
2️⃣ Виртуальный DOM
React создает виртуальную копию DOM в памяти и обновляет только те элементы, которые действительно изменились. Это делает приложения быстрее.
3️⃣ Однонаправленный поток данных
Данные передаются от родительских компонентов к дочерним через props. Это делает приложение предсказуемым:
4️⃣ JSX синтаксис
React использует JSX — расширение JavaScript, которое позволяет писать HTML-подобный код:
5️⃣ Декларативный подход
Вы описываете, как должен выглядеть интерфейс, а React сам решает, как это реализовать:
🖇 Ключевые преимущества:
- Переиспользование кода — компоненты можно использовать многократно
- Производительность — виртуальный DOM оптимизирует обновления
- Большая экосистема — множество готовых решений и библиотек
- Активное сообщество — поддержка Facebook и миллионов разработчиков
React идеально подходит для создания:
✅ Одностраничных приложений (SPA)
✅ Интерактивных пользовательских интерфейсов
✅ Крупных проектов с командной разработкой
✅ Приложений, требующих высокой производительности
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
React — это JavaScript-библиотека для создания пользовательских интерфейсов, разработанная Facebook. Она позволяет строить интерактивные веб-приложения с помощью компонентов.
React разбивает интерфейс на независимые компоненты, которые можно переиспользовать:
function Button({ text, onClick }) {
return <button onClick={onClick}>{text}</button>;
}
// Переиспользуем компонент
<Button text="Сохранить" onClick={handleSave} />
<Button text="Отмена" onClick={handleCancel} />
React создает виртуальную копию DOM в памяти и обновляет только те элементы, которые действительно изменились. Это делает приложения быстрее.
Данные передаются от родительских компонентов к дочерним через props. Это делает приложение предсказуемым:
function Parent() {
const [count, setCount] = useState(0);
return <Child count={count} />; // Данные идут вниз
}
React использует JSX — расширение JavaScript, которое позволяет писать HTML-подобный код:
const element = <h1>Привет, {name}!</h1>;
Вы описываете, как должен выглядеть интерфейс, а React сам решает, как это реализовать:
// Описываем желаемый результат
return (
<div>
{isLoggedIn ? <Dashboard /> : <LoginForm />}
</div>
);
- Переиспользование кода — компоненты можно использовать многократно
- Производительность — виртуальный DOM оптимизирует обновления
- Большая экосистема — множество готовых решений и библиотек
- Активное сообщество — поддержка Facebook и миллионов разработчиков
React идеально подходит для создания:
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7
#React
🚩 Когда React.memo действительно помогает, а когда только вредит?
React.memo — это инструмент оптимизации, который многие используют неправильно, думая, что он всегда ускоряет приложение.
React.memo предотвращает ре-рендер компонента, если его props не изменились. Звучит здорово, но есть подвох: сравнение props тоже требует времени. Если props постоянно меняются или компонент легковесный, memo только замедлит работу.
React.memo эффективен только когда компонент часто получает одинаковые props или когда его рендеринг действительно "дорогой" (сложные вычисления, много элементов DOM).
Главная ошибка — обернуть компонент в memo, но передавать ему новые объекты или функции каждый раз. В таком случае memo бесполезен, потому что props формально всегда "разные".
Пример:
Используйте React.memo для тяжелых компонентов со стабильными props. Не используйте для простых компонентов или когда props постоянно меняются.
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
React.memo — это инструмент оптимизации, который многие используют неправильно, думая, что он всегда ускоряет приложение.
React.memo предотвращает ре-рендер компонента, если его props не изменились. Звучит здорово, но есть подвох: сравнение props тоже требует времени. Если props постоянно меняются или компонент легковесный, memo только замедлит работу.
React.memo эффективен только когда компонент часто получает одинаковые props или когда его рендеринг действительно "дорогой" (сложные вычисления, много элементов DOM).
Главная ошибка — обернуть компонент в memo, но передавать ему новые объекты или функции каждый раз. В таком случае memo бесполезен, потому что props формально всегда "разные".
Пример:
// Плохо - props всегда новые
function Parent() {
return <Child onClick={() => {}} style={{color: 'red'}} />
}
const Child = React.memo(({onClick, style}) => <button />);
// memo не сработает - функция и объект каждый раз новые
// Хорошо - стабильные props
function Parent() {
const handleClick = useCallback(() => {}, []);
const style = useMemo(() => ({color: 'red'}), []);
return <Child onClick={handleClick} style={style} />
}
Используйте React.memo для тяжелых компонентов со стабильными props. Не используйте для простых компонентов или когда props постоянно меняются.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤2
#React
🚩 Почему React Context может убить производительность вашего приложения?
React Context — это удобно, но при неправильном использовании превращается в "пожирателя производительности".
Главная проблема Context в том, что при изменении его значения перерисовываются ВСЕ компоненты, которые его используют. Даже те, которым эти изменения совершенно не нужны.
❌ Типичная ошибка — создать один "супер-контекст" со всеми данными приложения: пользователь, тема, корзина, уведомления. При добавлении товара в корзину перерисовывается весь интерфейс, включая компоненты, которые показывают только тему оформления.
✅ Правильный подход — разделять Context по доменам. Отдельный контекст для пользователя, отдельный для темы, отдельный для корзины. Тогда изменения в корзине не затронут компоненты темы.
Еще одна проблема — передача нового объекта в value каждый рендер. React считает объекты разными, даже если их содержимое одинаковое, и запускает перерисовку всех потребителей.
Пример:
Используйте Context для редко меняющихся данных (тема, язык, пользователь). Для частых обновлений лучше выбрать специализированные решения вроде Zustand или React Query.
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
React Context — это удобно, но при неправильном использовании превращается в "пожирателя производительности".
Главная проблема Context в том, что при изменении его значения перерисовываются ВСЕ компоненты, которые его используют. Даже те, которым эти изменения совершенно не нужны.
Еще одна проблема — передача нового объекта в value каждый рендер. React считает объекты разными, даже если их содержимое одинаковое, и запускает перерисовку всех потребителей.
Пример:
// Плохо - новый объект каждый рендер
function Provider({children}) {
const [user, setUser] = useState();
return (
<Context.Provider value={{user, setUser}}> // Всегда новый объект!
{children}
</Context.Provider>
);
}
// Хорошо - стабильное значение
function Provider({children}) {
const [user, setUser] = useState();
const value = useMemo(() => ({user, setUser}), [user]);
return (
<Context.Provider value={value}>
{children}
</Context.Provider>
);
}
Используйте Context для редко меняющихся данных (тема, язык, пользователь). Для частых обновлений лучше выбрать специализированные решения вроде Zustand или React Query.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤2
#React
🚩 Почему key={index} в React — это не просто warning, а реальная проблема?
React использует ключи для определения, какие элементы изменились, добавились или удалились. Когда вы используете индекс как ключ, React не может корректно отследить элементы при изменении порядка списка.
Это приводит к тому, что React переиспользует компоненты не по назначению, сохраняя состояние там, где его быть не должно.
Классический пример проблемы:
📎 Проблемы key={index}:
🟣 Потеря состояния компонентов — фокус, введенный текст, анимации
🟣 Неправильные обновления — React обновляет не те элементы
🟣 Проблемы с производительностью — лишние перерендеры и создания компонентов
🟣 Баги в формах — значения полей "перепрыгивают" между элементами
Когда index может быть приемлемым:
Статический список — никогда не изменяется порядок
Без состояния — компоненты не хранят внутреннее состояние
Простой вывод — только отображение данных без интерактивности
Пагинация — каждая страница загружается заново
✅ Правильные практики:
- Используйте уникальные и стабильные идентификаторы
- Ключ должен быть одинаковым для одного элемента между рендерами
- Избегайте генерации ключей внутри render функции
- Тестируйте изменение порядка элементов
❌ Избегайте:
- key={index} для динамических списков
- Случайных ключей (Math.random(), Date.now() в рендере)
- Одинаковых ключей для разных элементов
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
React использует ключи для определения, какие элементы изменились, добавились или удалились. Когда вы используете индекс как ключ, React не может корректно отследить элементы при изменении порядка списка.
Это приводит к тому, что React переиспользует компоненты не по назначению, сохраняя состояние там, где его быть не должно.
Классический пример проблемы:
// Плохо - key={index} ломает логику
function TodoList({ todos }) {
return (
<ul>
{todos.map((todo, index) => (
<TodoItem
key={index} // Индекс как ключ!
todo={todo}
onComplete={() => completeTodo(todo.id)}
/>
))}
</ul>
);
}
// При удалении первого элемента:
// Было: [0: "Купить молоко", 1: "Погулять с собакой", 2: "Написать код"]
// Стало: [0: "Погулять с собакой", 1: "Написать код"]
// React думает, что изменился последний элемент, а не первый!
// Хорошо - уникальный и стабильный ключ
function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => (
<TodoItem
key={todo.id} // Стабильный уникальный ключ
todo={todo}
onComplete={() => completeTodo(todo.id)}
/>
))}
</ul>
);
}
Когда index может быть приемлемым:
Статический список — никогда не изменяется порядок
Без состояния — компоненты не хранят внутреннее состояние
Простой вывод — только отображение данных без интерактивности
Пагинация — каждая страница загружается заново
- Используйте уникальные и стабильные идентификаторы
- Ключ должен быть одинаковым для одного элемента между рендерами
- Избегайте генерации ключей внутри render функции
- Тестируйте изменение порядка элементов
- key={index} для динамических списков
- Случайных ключей (Math.random(), Date.now() в рендере)
- Одинаковых ключей для разных элементов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤2
#React
🚩 Почему useEffect с пустым массивом зависимостей — это не componentDidMount?
Многие React разработчики думают, что useEffect(() => {}, []) — это прямой аналог componentDidMount из классовых компонентов. На самом деле это опасное заблуждение, которое приводит к тонким багам и проблемам с производительностью.
Главное отличие в том, что useEffect выполняется ПОСЛЕ рендера и обновления DOM, а componentDidMount — сразу после монтирования. Но есть гораздо более серьезная проблема: в React 18+ с Strict Mode компоненты могут размонтироваться и смонтироваться заново для проверки корректности cleanup функций.
Это значит, что ваш "одноразовый" useEffect может выполниться дважды!
Типичная ошибка — думать, что код выполнится только один раз:
Правильный подход — всегда писать cleanup функции:
📎 Ключевые отличия от componentDidMount:
🟣 Время выполнения — после обновления DOM, не сразу после монтирования
🟣 Strict Mode — может выполняться дважды в development режиме
🟣 Cleanup обязателен — React ожидает возможность "отменить" эффект
🟣 Concurrent Features — в будущих версиях React эффекты могут прерываться
Еще одна проблема — попытка имитировать componentWillUnmount через cleanup функцию. Cleanup вызывается не только при размонтировании, но и перед каждым повторным выполнением эффекта.
✅ Безопасные практики:
- Всегда пишите cleanup функции для асинхронных операций
- Тестируйте компоненты с включенным Strict Mode
- Используйте флаги отмены для предотвращения race conditions
- Помните: cleanup ≠ componentWillUnmount
❌ Избегайте:
- Предположений о единоразовом выполнении useEffect
- Побочных эффектов без возможности их отмены
- Прямого сравнения с методами жизненного цикла классов
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Многие React разработчики думают, что useEffect(() => {}, []) — это прямой аналог componentDidMount из классовых компонентов. На самом деле это опасное заблуждение, которое приводит к тонким багам и проблемам с производительностью.
Главное отличие в том, что useEffect выполняется ПОСЛЕ рендера и обновления DOM, а componentDidMount — сразу после монтирования. Но есть гораздо более серьезная проблема: в React 18+ с Strict Mode компоненты могут размонтироваться и смонтироваться заново для проверки корректности cleanup функций.
Это значит, что ваш "одноразовый" useEffect может выполниться дважды!
Типичная ошибка — думать, что код выполнится только один раз:
// Плохо - может выполниться дважды в development!
useEffect(() => {
fetchUserData(); // Запрос может дублироваться
initializeAnalytics(); // Аналитика инициализируется дважды
startWebSocket(); // Создается два подключения!
}, []); // Пустой массив НЕ гарантирует одноразовое выполнение
Правильный подход — всегда писать cleanup функции:
// Хорошо - учитываем возможное повторное выполнение
useEffect(() => {
let cancelled = false;
const fetchData = async () => {
const data = await fetchUserData();
if (!cancelled) {
setUser(data);
}
};
fetchData();
return () => {
cancelled = true; // Cleanup предотвращает обновление состояния
};
}, []);
Еще одна проблема — попытка имитировать componentWillUnmount через cleanup функцию. Cleanup вызывается не только при размонтировании, но и перед каждым повторным выполнением эффекта.
// Неправильное понимание cleanup
useEffect(() => {
const timer = setInterval(tick, 1000);
return () => {
clearInterval(timer); // Вызывается НЕ только при размонтировании!
};
}, [someValue]); // При изменении someValue cleanup тоже сработает
- Всегда пишите cleanup функции для асинхронных операций
- Тестируйте компоненты с включенным Strict Mode
- Используйте флаги отмены для предотвращения race conditions
- Помните: cleanup ≠ componentWillUnmount
- Предположений о единоразовом выполнении useEffect
- Побочных эффектов без возможности их отмены
- Прямого сравнения с методами жизненного цикла классов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1
#React
🚩 Почему useState с объектами и массивами ломает React и как это исправить?
React использует Object.is() для сравнения состояния, а не глубокое сравнение. Когда вы мутируете объект или массив напрямую, ссылка остается той же, и React думает, что ничего не изменилось. Компонент не перерендеривается, UI не обновляется.
Это создает "призрачные баги" — состояние в DevTools показывает новые данные, но интерфейс отображает старые.
Типичные ошибки с мутациями:
Правильный подход — иммутабельные обновления:
📎 Проблемы мутаций в React:
🟣 Пропущенные рендеры — UI не синхронизирован с состоянием
🟣 Баги в useEffect — зависимости не отслеживают мутации
🟣 Проблемы с memo — оптимизация не работает
🟣 Race conditions — асинхронные обновления перезаписывают изменения
Особенно опасны мутации в useEffect:
✅ Инструменты для иммутабельности:
- Spread оператор для простых случаев
- Immer для сложных структур
- Ramda/Lodash fp для функционального подхода
- useImmer хук для удобства
❌ Избегайте:
- Прямых мутаций state объектов и массивов
- Методов типа push(), pop(), sort() на state массивах
- Изменения вложенных свойств без создания новых объектов
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
React использует Object.is() для сравнения состояния, а не глубокое сравнение. Когда вы мутируете объект или массив напрямую, ссылка остается той же, и React думает, что ничего не изменилось. Компонент не перерендеривается, UI не обновляется.
Это создает "призрачные баги" — состояние в DevTools показывает новые данные, но интерфейс отображает старые.
Типичные ошибки с мутациями:
// Плохо - мутация массива
const [items, setItems] = useState([1, 2, 3]);
const addItem = () => {
items.push(4); // Мутация!
setItems(items); // React не увидит изменений
};
// Плохо - мутация объекта
const [user, setUser] = useState({name: 'John', age: 25});
const updateAge = () => {
user.age = 26; // Мутация!
setUser(user); // Ссылка та же, React не обновится
};
Правильный подход — иммутабельные обновления:
// Хорошо - новый массив
const addItem = () => {
setItems([...items, 4]); // Новая ссылка
};
const removeItem = (index) => {
setItems(items.filter((_, i) => i !== index));
};
// Хорошо - новый объект
const updateAge = () => {
setUser({...user, age: 26}); // Новая ссылка
};
// Для сложных объектов используйте immer
const updateUser = () => {
setUser(produce(user, draft => {
draft.profile.settings.theme = 'dark';
}));
};
Особенно опасны мутации в useEffect:
// Плохо - бесконечный цикл или пропущенные обновления
useEffect(() => {
data.processed = true; // Мутация в зависимости!
setData(data);
}, [data]); // data ссылка не изменилась, эффект может не сработать
- Spread оператор для простых случаев
- Immer для сложных структур
- Ramda/Lodash fp для функционального подхода
- useImmer хук для удобства
- Прямых мутаций state объектов и массивов
- Методов типа push(), pop(), sort() на state массивах
- Изменения вложенных свойств без создания новых объектов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥3❤2
#React
🚩 Почему React.lazy может ухудшить ранжирование в Google?
Хотя Googlebot умеет выполнять JavaScript, React.lazy создает задержки в рендере, которые напрямую влияют на Core Web Vitals — ключевые метрики для ранжирования в поиске.
Когда критически важный контент загружается через lazy loading, страница показывает Largest Contentful Paint (LCP) только после загрузки чанка. Это может увеличить LCP с 1.2 секунды до 3+ секунд, что переводит страницу из "хорошей" в "плохую" категорию.
Google использует Page Experience как фактор ранжирования. Медленный LCP = плохой пользовательский опыт = падение позиций в выдаче.
SSR приложения сталкиваются с другой проблемой — React.lazy не работает на сервере. Нужны дополнительные библиотеки типа @loadable/component, иначе сервер не сможет отрендерить страницу полностью.
📎 Как React.lazy влияет на SEO метрики:
🟣 LCP задержка — основной контент загружается позже
🟣 CLS проблемы — скачки layout при подгрузке компонентов
🟣 FID ухудшение — JavaScript блокируется на загрузке чанков
🟣 Crawl Budget — роботу нужно больше времени на индексацию
📎 Что безопасно делать lazy:
🟣 Модальные окна и overlays
🟣 Интерактивные виджеты ниже основного контента
🟣 Административные интерфейсы
🟣 Второстепенные функции (комментарии, рекомендации)
Особенно критично для мобильной индексации — Google в первую очередь оценивает мобильную версию. На медленных соединениях задержки от lazy loading многократно увеличиваются.
Современный подход — использовать lazy loading для улучшения первоначальной загрузки страницы, но держать весь above-the-fold контент в основном бандле.
✅ Безопасная стратегия:
❌ Избегайте:
React.lazy не убьет индексацию, но может серьезно ударить по производительности и ранжированию!
🔎 🔎 🔎 🔎 🔄
#⃣ Новости
#⃣ База вопросов
Хотя Googlebot умеет выполнять JavaScript, React.lazy создает задержки в рендере, которые напрямую влияют на Core Web Vitals — ключевые метрики для ранжирования в поиске.
Когда критически важный контент загружается через lazy loading, страница показывает Largest Contentful Paint (LCP) только после загрузки чанка. Это может увеличить LCP с 1.2 секунды до 3+ секунд, что переводит страницу из "хорошей" в "плохую" категорию.
Google использует Page Experience как фактор ранжирования. Медленный LCP = плохой пользовательский опыт = падение позиций в выдаче.
// Проблема - основной контент в lazy компоненте
const ProductCard = React.lazy(() => import('./ProductCard'));
// LCP срабатывает только после загрузки чанка!
SSR приложения сталкиваются с другой проблемой — React.lazy не работает на сервере. Нужны дополнительные библиотеки типа @loadable/component, иначе сервер не сможет отрендерить страницу полностью.
Особенно критично для мобильной индексации — Google в первую очередь оценивает мобильную версию. На медленных соединениях задержки от lazy loading многократно увеличиваются.
Современный подход — использовать lazy loading для улучшения первоначальной загрузки страницы, но держать весь above-the-fold контент в основном бандле.
- Above-the-fold контент загружайте сразу
- Lazy loading только для below-the-fold элементов
- Мониторьте Core Web Vitals в Google Search Console
- Используйте @loadable/component для SSR
- Lazy loading hero секций, заголовков, основных изображений
- React.lazy без SSR поддержки
- Множественных lazy компонентов на одной странице
- Lazy loading контента, влияющего на LCP
React.lazy не убьет индексацию, но может серьезно ударить по производительности и ранжированию!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1🔥1