React
2.74K subscribers
318 photos
131 videos
14 files
377 links
Подборки по React js и все что с ним связано. По всем вопросам @evgenycarter
Download Telegram
🎯 Сегодня покажу вам простой, но мощный приём: как ускорить React-приложение с помощью мемоизации списков

Каждый из нас рендерит списки: товары, заявки, комментарии, юзеров - список бесконечен.
И одна из самых частых проблем: каждый элемент списка перерендеривается даже при минимальном изменении родителя.

Сегодня разбираем реальный кейс и решение, которое спасает производительность.

🔥 Проблема

У нас есть список задач, и при обновлении одной задачи - перерендериваются все элементы списка.
Визуально это незаметно, но при больших списках производительность падает.

Причина проста: у каждого элемента меняется ссылка на props → компонент считается обновлённым → React перерендеривает его.


💡 Решение: React.memo + useCallback

Вот минимальный рабочий пример.

Компонент элемента списка


const TaskItem = React.memo(function TaskItem({ task, onToggle }) {
console.log("Render:", task.title);
return (
<div>
<input
type="checkbox"
checked={task.done}
onChange={() => onToggle(task.id)}
/>
{task.title}
</div>
);
});


Родитель


function TaskList() {
const [tasks, setTasks] = useState(data);

const toggle = useCallback(id => {
setTasks(prev =>
prev.map(t => (t.id === id ? { ...t, done: !t.done } : t))
);
}, []);

return tasks.map(task => (
<TaskItem key={task.id} task={task} onToggle={toggle} />
));
}



🚀 Что это даёт?

- React.memo не даст компоненту перерендериться без изменения реальных данных.
- useCallback создаёт стабильную ссылку на функцию.
- Итог: перерендерятся только изменённые элементы, остальное остаётся нетронутым.

При 500+ элементах разница ощущается моментально.

✍️ @React_lib
👍61😁1
Кастомные хуки (Custom Hooks). Создаем свой первый кастомный хук useWindowSize

Сегодня напишем простой, но очень полезный хук - useWindowSize. Он будет отслеживать ширину и высоту окна браузера. Это пригодится, если вам нужно менять верстку (например, скрывать сайдбар) при изменении размера экрана.

Мы создадим функцию, которая:

1. Использует useState для хранения размеров.
2. Использует useEffect для подписки на событие resize.
3. Важно: Не забываем удалять обработчик событий (cleanup function), чтобы не нагружать память!


Вот готовый пример. Можете сохранить его в файл useWindowSize.js.


import { useState, useEffect } from 'react';

// Наш кастомный хук
function useWindowSize() {
// 1. Инициализируем состояние
const [windowSize, setWindowSize] = useState({
width: undefined,
height: undefined,
});

useEffect(() => {
// Функция для обновления состояния
function handleResize() {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
}

// Устанавливаем размер сразу при загрузке
handleResize();

// 2. Добавляем слушатель события изменения размера окна
window.addEventListener("resize", handleResize);

// 3. Очистка: удаляем слушатель при размонтировании
return () => window.removeEventListener("resize", handleResize);
}, []); // Пустой массив зависимостей = запускаем один раз

return windowSize;
}

export default useWindowSize;


🚀 Как это использовать в компоненте?

Теперь ваш компонент становится чистым и понятным. Никакой лишней логики внутри!


import React from 'react';
import useWindowSize from './useWindowSize';

const App = () => {
// Просто вызываем наш хук
const { width, height } = useWindowSize();

return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>📏 Размер окна</h1>
<p>Ширина: <strong>{width}px</strong></p>
<p>Высота: <strong>{height}px</strong></p>

{width < 600 ? (
<p>📱 Похоже, вы на мобильном устройстве!</p>
) : (
<p>💻 Это десктопная версия.</p>
)}
</div>
);
};

export default App;


✍️ @React_lib
👍41
🚀 Что такое условный рендеринг в React и зачем он нужен?

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

Думайте об этом как о "if... else...", но для вашего пользовательского интерфейса (UI).


- ЕСЛИ пользователь вошел в систему, ТО показать компонент <UserProfile />.

- ИНАЧЕ показать компонент <LoginForm />.


💡 Для чего он нужен?

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

Он нужен буквально повсюду. Вот самые частые примеры:

- Пока идет загрузка данных с сервера: Мы показываем <Spinner /> (крутилку). Как только данные пришли — показываем <DataList />.

- Аутентификация: Показываем "Профиль", если isLoggedIn === true, и "Войти", если isLoggedIn === false.

- Обработка ошибок: Если при загрузке произошла ошибка, мы показываем <ErrorMessage /> вместо контента.

- Пустые состояния: Показываем "Ваша корзина пуста", если cart.items.length === 0, и список товаров, если в ней что-то есть.

- Интерактив: Показ/скрытие модальных окон, выпадающих меню или вкладок по клику.


🛠️ Как это сделать?

В React есть несколько популярных способов:

1. Тернарный оператор (? :) - самый частый выбор.
{isLoading ? <Spinner /> : <Content />}

2. Логический оператор "И" (&&) - идеален, когда вам нужно что-то показать или не показать ничего (нет ветки "else").
{hasMessages && <NotificationBadge />}

3. Обычный if/else - используется внутри тела компонента, до return, для более сложной логики.

Условный рендеринг - это не просто "фича", это сам смысл React. Это то, что позволяет вашему UI реагировать на изменения данных и действия пользователя.

#React #JavaScript #Frontend #Development #ConditionalRendering

✍️ @React_lib
👍53
🔥 Антипаттерн в React: избыточные зависимости useEffect

Встречали такое?


useEffect(() => {
fetchData(id);
}, [id, fetchData]);


❗️Проблема: fetchData — это функция, которая переопределяется при каждом рендере. В итоге эффект срабатывает чаще, чем должен, даже если id не менялся.

👎 Это вызывает лишние запросы, лаги и баги в логике.

💡 Решения:

1. Обёрнуть в useCallback:


const fetchData = useCallback((id: string) => {
// ...
}, []);


2. Вынести вне компонента (если она не зависит от состояния):


const fetchData = (id: string) => {
// ...
};


3. Игнорировать в зависимостях (как временный хак, но осторожно!):


// eslint-disable-next-line react-hooks/exhaustive-deps


Правильное управление зависимостями в useEffect — ключ к стабильному и предсказуемому поведению компонентов.

✍️ @React_lib
👍4
Сегодня хочу поговорить про типичную боль React-разработчиков - лишние ререндеры.

Я регулярно вижу код, где приложение «тормозит», хотя логика простая. В 80% случаев причина банальна: компоненты перерисовываются без необходимости.

Что я проверяю в первую очередь

1️⃣ props меняются по ссылке


<Component data={{ a: 1 }} />


Каждый рендер - новый объект → новый ререндер.
Решение: useMemo.

2️⃣ функции создаются заново


onClick={() => doSomething()}


Если компонент обёрнут в memo - он всё равно будет ререндериться.
Решение: useCallback.

3️⃣ memo используется «для галочки»
React.memo без анализа - зло.
Если props всегда новые → memo бесполезен и даже мешает.

4️⃣ state лежит слишком высоко
Когда useState в родителе, а нужен только одному дочернему компоненту - привет лишним обновлениям.

Мой личный чек-лист

💚 Сначала DevTools → Highlight updates
💚 Потом проверяю ссылки
💚 И только в конце - memo, useMemo, useCallback

⚠️ Важно: оптимизация, это не рефлекс, а осознанный шаг. Сначала простота, потом скорость.

✍️ @React_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10😁2
⚛️ Реактивность - это просто (и всего 35 строк кода)

Мы часто воспринимаем реактивность в современных фреймворках (Vue, Solid, MobX или Preact Signals) как некую "магию". Кажется, что под капотом там сложные механизмы, доступные только избранным архитекторам.

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

В статье «Reactivity is easy» он разбирает ключевые концепции:
🔹 Signals (Сигналы) — контейнеры для значений.
🔹 Effects (Эффекты) — функции, которые реагируют на изменения.
🔹 Dependency Tracking — как именно эффект "узнает", на какие сигналы он подписан (спойлер: через глобальный контекст).

Отличный материал для тех, кто хочет перестать бояться "магии" стейт-менеджеров и понять, как всё работает на уровне чистого JS.

👉 Читать статью: https://romgrk.com/posts/reactivity-is-easy

#js #frontend #reactivity #architecture

✍️ @React_lib
👍3
Как перестать страдать с зависимостями в useEffect

Сегодня покажу приём, который резко снижает боль от “почему эффект снова сработал” и “ESLint ругается на deps”.

Типичный кейс: в useEffect ты подписываешься на что-то и используешь колбэк/данные, которые постоянно меняются → эффект перезапускается, подписки пересоздаются.

Решение: “стабильный эффект + актуальные данные через ref”

Идея простая:

🔹эффект запускается редко (или 1 раз),
🔹а внутри всегда используются самые свежие значения через ref.

Пример (мини-хук):


function useLatest(value) {
const ref = React.useRef(value);
React.useEffect(() => { ref.current = value; }, [value]);
return ref;
}


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


const onMessageLatest = useLatest(onMessage);

React.useEffect(() => {
const unsub = socket.subscribe((msg) => {
onMessageLatest.current(msg);
});
return unsub;
}, []); // подписка не пересоздаётся


Что это даёт:

🔹подписки/таймеры/листенеры не пересоздаются на каждую мелочь,
🔹зависимости в эффекте становятся честными,
🔹меньше неожиданных “петель”.

✍️ @React_lib
👎5👍1
Как frontend-разработчику получить оффер в Big Tech?

Платят как джуну, а спрашивают как с лида 🙄 Зарплата не растёт, задачи скучные.

Пробуешь откликаться, но на резюме клюют только ноунейм компании, а на собесах валят на алгоритмах? При этом вокруг кто-то постоянно получает офферы в Яндекс или VK...

Стабильность с маленькой зп, или дестрой рынка и выход на максимальную? Синяя или красная таблетка, Нео?! 👾

Меня зовут Тихон, привет! Я — действующий Frontend-разработчик и ментор.

Помогаю устроиться на хорошие позиции в Big Tech и сопровождаю на испытательном сроке.


В своем канале:
👉Разбираю самые популярные и каверзные вопросы на собесах
👉Рассказываю как пройти фильтр HR
👉Борюсь с убеждениями, которые мешают развиваться
👉Делюсь лайфхаками, например как аккуратно “пинговать” рекрутеров

Регулярно публикую полезные материалы:

▪️60 вопросов, которые точно помогут тебе на собеседовании.
▪️Подборка из 100+ каналов с вакансиями для разработчиков
▪️
10 задротских вопросов про JavaScript, после которых ты усомнишься, что вообще знаешь JS. Часть 1
▪️Чек лист проверки своего резюме

Подписывайся, нас уже 4500 🤓: ссылка

Реклама, erid 2W5zFK9zMoW: ИП Галактионов Тихон Витальевич, ИНН 771618975809
useMemo и useCallback - когда они реально помогают, а когда вредят

Сегодня разберём больную тему: “обмазался мемоизацией - стало хуже”.

Когда useMemo/useCallback НЕ нужны

🔹Значение/функция не передаются в memo - компоненты и не используются как deps.
🔹Вычисление дешёвое (например, arr.map на 20 элементов).
🔹Ты добавил их “на всякий случай”.

Побочный эффект: ты усложняешь код и добавляешь лишнюю работу React (хранить кеш, сравнивать deps).

Когда они реально спасают

1. Стабильные пропсы для React.memo


const onSelect = React.useCallback((id) => {
setSelected(id);
}, []);


2. Тяжёлые вычисления


const filtered = React.useMemo(() => heavyFilter(items, query), [items, query]);


3. Объекты в deps (чтобы не триггерить эффекты/хуки)


const params = React.useMemo(() => ({ q: query, page }), [query, page]);


Быстрый чек-лист перед добавлением мемоизации

🔹Это реально горячая точка? (профайлер/замеры)
🔹Без мемоизации есть лишние рендеры дочерних memo?
🔹Или это просто “красивее выглядит”?

✍️ @React_lib
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Избегайте «прокидывания» пропсов (prop-drilling) для расширения компонентов

Вместо этого используйте композицию

✍️ @React_lib
👍3
Почему React-приложение “лагает” при вводе в инпут - и как починить за 3 минуты

Сегодня покажу классическую ситуацию: у тебя есть форма/поиск, ты печатаешь и интерфейс начинает подтормаживать. Чаще всего причина одна: на каждый onChange ты триггеришь тяжёлый ререндер (фильтрация, сортировка, построение списков, пересчёт графиков, сложные компоненты).

Быстрая диагностика

1. Открой React DevTools → Profiler
2. Запиши ввод в поле
3. Посмотри, кто ререндерится и сколько времени занимает

Три быстрых фикса (по популярности)

1) useDeferredValue для “тяжёлого” поиска

• Инпут обновляется мгновенно
• Тяжёлая часть догоняет “в фоне”

Идея: рендер списка завязываем не на query, а на deferredQuery.

2) useMemo для вычислений
Если делаешь filter/sort/map по большому массиву - мемоизируй результат по зависимостям.

3) Разделяй состояние
Частая ошибка: держать “всё” в одном компоненте.
Инпут сверху - список снизу. Если список тяжёлый, вынеси его в отдельный компонент + memo.

Мини-чеклист

• Есть ли тяжёлые вычисления в рендере?
• Ререндерится ли список при каждом вводе?
• Можно ли “отложить” вычисление (deferred)?
• Можно ли кешировать (memo)?
• Можно ли изолировать компонент?

✍️ @React_lib
👍3
Этот пост выкуплен под рекламную интеграцию.

Но здесь будут скрины от участников frontend-менторства Тихона Галактионова и подборка полезных материалов:


👉100 вопросов, которые точно помогут тебе на собеседовании: ссылка
👉Подборка из 100+ каналов с вакансиями для разработчиков: ссылка
👉10 задротских вопросов про JavaScript, после которых ты усомнишься, что вообще знаешь JS: ссылка
👉Чек лист проверки своего резюме: ссылка
👉Разбор самых популярных и каверзных вопросов на собесах: ссылка
👉Лайфхак как аккуратно “пинговать” рекрутеров: ссылка

Ссылка на канал Тихона, там же можно найти больше материалов для подготовки к собеседованиям в Big Tech: ссылка

Реклама, erid: 2W5zFH1z9Xo ИП Галактионов Тихон Витальевич, ИНН 771618975809
1👍1
Сегодня написал пост на тему, которая регулярно бьёт по скорости разработки: почему React-приложение “тормозит”, даже когда кажется, что код нормальный.

Часто вижу одну и ту же ситуацию:
компонент маленький, логика простая, данных немного, а интерфейс всё равно начинает дёргаться. Особенно в формах, таблицах и списках.

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

Вот 3 вещи, которые я первым делом проверяю:

1. Родитель слишком “шумный”
Если родительский компонент часто обновляет state, все дочерние компоненты тоже могут улетать в ререндер.
Даже если визуально ничего не меняется.

2. useMemo и useCallback не спасают автоматически
Их часто добавляют “на всякий случай”, но без понимания, где узкое место.
В итоге код становится сложнее, а пользы - ноль.

3. Ключи в списках
Нестабильные key - классика.
Если в списке стоит index, React может пересоздавать элементы там, где не должен.
Особенно больно это ощущается в интерактивных списках.

Мой рабочий подход простой:

• сначала открываю React DevTools Profiler
• нахожу, какой компонент ререндерится чаще всего
• проверяю, это реально нужно или нет
• только потом оптимизирую

Главная мысль:
не оптимизируйте React вслепую.
Сначала найдите источник лишних ререндеров.
Очень часто после этого оказывается, что фикс занимает 5 минут, а не 2 часа.

✍️ @React_lib
👍4
🚀 Подборка полезных IT каналов в Max


Системное администрирование, DevOps 📌

https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.

1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С

Программирование C++📌

https://max.ru/cpp_lib Библиотека C/C++ разработчика

Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика

Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика

GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных

Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков

Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов

Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻

Шутки программистов 📌
https://max.ru/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free

Книги, статьи для дизайнеров 📌

https://max.ru/odesigners Статьи, книги для дизайнеров

Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике

Вакансии 📌
https://max.ru/progjob Вакансии в IT

Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных


Бонус 📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
💩2
This media is not supported in your browser
VIEW IN TELEGRAM
Избегайте использования нескольких переменных состояния для отслеживания статуса.

Вместо этого используйте перечисления (enums).

✍️ @React_lib
👍9
🔧 Шпаргалка по базовым компонентам React



// Импорт React и роутера
import React, { useState, useEffect, createContext, useContext } from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';

// 1. Создание контекста
const MyContext = createContext();

// 2. Компонент с Context и useEffect
function Welcome() {
const contextValue = useContext(MyContext);

useEffect(() => {
console.log("Welcome component mounted or updated");
return () => console.log("Welcome component unmounted");
}, []);

return <h1>{contextValue}</h1>;
}

// 3. Управляемая форма
function FormComponent() {
const [inputValue, setInputValue] = useState('');
const handleChange = (e) => setInputValue(e.target.value);

return (
<div>
<h2>Controlled Form</h2>
<input type="text" value={inputValue} onChange={handleChange} />
<p>Input Value: {inputValue}</p>
</div>
);
}

// 4. Счётчик с состоянием и обработчиком
function Counter() {
const [count, setCount] = useState(0);

return (
<div>
<h2>Counter</h2>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

// 5. Рендер списка
function FruitList() {
const fruits = ['Apple', 'Banana', 'Orange'];
return (
<div>
<h2>Fruit List</h2>
<ul>
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
</div>
);
}

// 6. Условный рендеринг
function ConditionalRender({ isLoggedIn }) {
return (
<div>
<h2>Conditional Rendering</h2>
{isLoggedIn ? <p>Welcome back!</p> : <p>Please log in.</p>}
</div>
);
}

// 7. Навигация
function Navigation() {
return (
<nav>
<Link to="/">Home</Link> | <Link to="/form">Form</Link> | <Link to="/counter">Counter</Link> | <Link to="/fruits">Fruits</Link>
</nav>
);
}

// 8. Основной App с Router и Context
function App() {
return (
<MyContext.Provider value="Hello, Context!">
<Router>
<div style={{ padding: '20px', fontFamily: 'Arial' }}>
<Navigation />
<Switch>
<Route path="/" exact>
<Welcome />
<ConditionalRender isLoggedIn={true} />
</Route>
<Route path="/form" component={FormComponent} />
<Route path="/counter" component={Counter} />
<Route path="/fruits" component={FruitList} />
</Switch>
</div>
</Router>
</MyContext.Provider>
);
}

export default App;


✍️ @React_lib
👍3
💻Angular — один из самых строгих и системных инструментов разработки пользовательских интерфейсов. Его выбирают крупные компании, где важны масштабируемость, предсказуемость кода и возможность развивать продукт долгие годы. Мы расскажем вам как работать с этим инструментом. Записывайтесь на открытые уроки в преддверии старта курса «Angular-разработчик»:

📆26 марта в 20:00 МСК на открытом уроке разберём, как LLM ускоряют фронтенд-разработку. Покажем их развитие, подготовим Angular-проект к работе с ИИ, создадим приложение и обсудим, где ИИ реально помогает разработчику.

📆9 апреля в 20:00 МСК на открытом уроке разберём сигналы в Angular: создадим реактивную форму с валидацией, обсудим управление состоянием и сравним с подходом на RxJS.

📆21 апреля в 20:00 МСК разберём архитектуру Angular-приложения: слои, feature-подход, разделение UI, логики и API, а также паттерны и структуру реального проекта.

Подробности об уроках и регистрация: https://vk.cc/cVBtTH

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru