🔥 Антипаттерн в React: избыточные зависимости useEffect
Встречали такое?
❗️Проблема:
👎 Это вызывает лишние запросы, лаги и баги в логике.
💡 Решения:
1. Обёрнуть в useCallback:
2. Вынести вне компонента (если она не зависит от состояния):
3. Игнорировать в зависимостях (как временный хак, но осторожно!):
✅ Правильное управление зависимостями в
✍️ @React_lib
Встречали такое?
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
Не просто кнопка "Загрузить": Секреты работы с файлами в React
🎓 19 мая в 20:00 — бесплатный вебинар для разработчиков, которые хотят делать удобную и безопасную загрузку файлов в React-приложениях.
Что покажем:
— Drag & Drop, предпросмотр, валидация — всё, что ждали от UX;
— Обработка PDF, Excel и изображений прямо в браузере;
— Как не «положить» интерфейс при загрузке тяжёлых файлов;
— Защита от XSS, проверка MIME-типов и другие нюансы безопасности.
📌 Для фронтендеров и fullstack-разработчиков, которым важна клиентская оптимизация.
В программе — реальные примеры кода, которые можно сразу использовать.
Урок пройдет в преддверии старта курса «React.js Developer». Каждый участник вебинара получит скидку на обучение.
Регистрация: https://vk.cc/cLZMN5
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🎓 19 мая в 20:00 — бесплатный вебинар для разработчиков, которые хотят делать удобную и безопасную загрузку файлов в React-приложениях.
Что покажем:
— Drag & Drop, предпросмотр, валидация — всё, что ждали от UX;
— Обработка PDF, Excel и изображений прямо в браузере;
— Как не «положить» интерфейс при загрузке тяжёлых файлов;
— Защита от XSS, проверка MIME-типов и другие нюансы безопасности.
📌 Для фронтендеров и fullstack-разработчиков, которым важна клиентская оптимизация.
В программе — реальные примеры кода, которые можно сразу использовать.
Урок пройдет в преддверии старта курса «React.js Developer». Каждый участник вебинара получит скидку на обучение.
Регистрация: https://vk.cc/cLZMN5
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Сегодня поговорим о Zustand — суперлёгкой и мощной библиотеке для управления состоянием в React-приложениях.
🧵 Минимализм состояния с Zustand
Создание стора занимает меньше минуты:
🎯 Как использовать в компоненте:
🧠 Чем хорош Zustand:
* Нет провайдеров.
* Нет бойлерплейта.
* Поддержка middlewares, persist, subscriptions.
* Работает в Next.js, React Native, даже вне React.
Zustand идеально подходит для маленьких и средних приложений. Простой API — максимум гибкости.
✍️ @React_lib
🧵 Минимализм состояния с Zustand
Создание стора занимает меньше минуты:
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
}));
🎯 Как использовать в компоненте:
const Counter = () => {
const { count, increase } = useStore();
return (
<button onClick={increase}>
Count: {count}
</button>
);
};
🧠 Чем хорош Zustand:
* Нет провайдеров.
* Нет бойлерплейта.
* Поддержка middlewares, persist, subscriptions.
* Работает в Next.js, React Native, даже вне React.
Zustand идеально подходит для маленьких и средних приложений. Простой API — максимум гибкости.
✍️ @React_lib
🚧 TanStack DB — это TypeScript-first библиотека для управления данными и кэшированием, вдохновлённая такими инструментами, как tRPC, TanStack Query, Drizzle, Kysely, RxJS, MobX, Signal, SWR, Zustand и другими.
Что такое TanStack DB?
TanStack DB — это реактивная, абстрактная система управления данными с поддержкой провайдеров и кэшированием, ориентированная на работу с "запросами", "данными" и "реактивностью".
Ты описываешь структуру данных (схему), подключаешь источник данных (провайдер), и всё остальное — магия ✨:
* TanStack DB умеет работать с асинхронными источниками данных
* Обновления реактивны: изменения автоматически отражаются во всех связанных компонентах
* Поддерживаются "live queries" — данные автоматически обновляются при изменении источника
* Под капотом используются сигналы и абстракции, напоминающие RxJS, но с более простым API
https://github.com/TanStack/db
✍️ @React_lib
Что такое TanStack DB?
TanStack DB — это реактивная, абстрактная система управления данными с поддержкой провайдеров и кэшированием, ориентированная на работу с "запросами", "данными" и "реактивностью".
Ты описываешь структуру данных (схему), подключаешь источник данных (провайдер), и всё остальное — магия ✨:
* TanStack DB умеет работать с асинхронными источниками данных
* Обновления реактивны: изменения автоматически отражаются во всех связанных компонентах
* Поддерживаются "live queries" — данные автоматически обновляются при изменении источника
* Под капотом используются сигналы и абстракции, напоминающие RxJS, но с более простым API
https://github.com/TanStack/db
✍️ @React_lib
💻 Хотите стать востребованным Fullstack-разработчиком?
Откройте для себя новые возможности с обучением OTUS!
❗️ На курсе вы научитесь всему, что нужно для того, чтобы стать универсальным разработчиком, который создает как фронтенд, так и серверную часть веб-приложений. Освоите: HTML, CSS, JavaScript, React, TypeScript, Node.js и многое другое. Пройдете все этапы разработки, от верстки до серверной настройки.
По окончании программы у вас будет:
✅ 3 реальных проекта в портфолио
✅ Навыки, необходимые для работы в крупных компаниях
✅ Готовность к собеседованиям
✅ Уверенное понимание процесса разработки
✅ Возможность участвовать в интересных проектах
➡️ Оставьте заявку прямо сейчас: https://vk.cc/cMaCmG
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Откройте для себя новые возможности с обучением OTUS!
По окончании программы у вас будет:
✅ 3 реальных проекта в портфолио
✅ Навыки, необходимые для работы в крупных компаниях
✅ Готовность к собеседованиям
✅ Уверенное понимание процесса разработки
✅ Возможность участвовать в интересных проектах
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Как создать свой кастомный хук
В реальных приложениях иногда нужно сравнивать текущее и предыдущее состояние — например, чтобы анимировать изменения или вызывать сайд-эффекты только при росте/падении значения. Сегодня покажу, как легко вынести логику в переиспользуемый хук.
Почему это круто:
* ✅ Логика хранения предыдущих значений вынесена в один хук — нет дублирования кода.
* ✅
* ✅ Помогает сравнивать и реагировать на изменения (анимации, уведомления, условные запросы).
Попробуйте интегрировать
✍️ @React_lib
usePrevious
для хранения предыдущего значения пропсов или стейта в компонентах React.В реальных приложениях иногда нужно сравнивать текущее и предыдущее состояние — например, чтобы анимировать изменения или вызывать сайд-эффекты только при росте/падении значения. Сегодня покажу, как легко вынести логику в переиспользуемый хук.
import { useRef, useEffect } from 'react';
/**
* Хук usePrevious сохраняет предыдущее значение value.
* @param {T} value — текущее значение (пропс или стейт)
* @returns {T | undefined} — предыдущий value (или undefined при первом рендере)
*/
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
// Пример использования:
import React, { useState } from 'react';
export default function PriceTracker() {
const [price, setPrice] = useState(100);
const prevPrice = usePrevious(price);
const getTrend = () => {
if (prevPrice === undefined) return '—';
return price > prevPrice ? '📈' : price < prevPrice ? '📉' : '➖';
};
return (
<div>
<h2>Цена: {price} {getTrend()}</h2>
<button onClick={() => setPrice(p => p + 5)}>↑ Увеличить</button>
<button onClick={() => setPrice(p => p - 5)}>↓ Уменьшить</button>
</div>
);
}
Почему это круто:
* ✅ Логика хранения предыдущих значений вынесена в один хук — нет дублирования кода.
* ✅
usePrevious
работает и для пропсов, и для стейта.* ✅ Помогает сравнивать и реагировать на изменения (анимации, уведомления, условные запросы).
Попробуйте интегрировать
usePrevious
в свои компоненты, где нужно отслеживать изменение данных во времени. Поделитесь в комментариях, в каких кейсах вы уже использовали или планируете применить такой хук!✍️ @React_lib
🔥 Сегодня расскажу о том, как грамотно управлять состоянием форм в React
Наверняка каждый из нас сталкивался с мучительными попытками организовать удобный менеджмент форм. Хочется, чтобы всё было понятно, компактно и легко поддерживаемо. Вот пара рекомендаций:
1️⃣ React Hook Form — сейчас это самый популярный способ работы с формами. Отличная производительность, минимальное количество ререндеров и простая интеграция с валидацией.
2️⃣ Formik — проверенная годами библиотека, немного проигрывает в скорости, но выигрывает по удобству работы с комплексными формами и кастомными решениями.
Мой личный совет: используйте React Hook Form для небольших и средних проектов. Если же требуется высокая кастомизация и много логики, Formik остаётся отличным вариантом.
А вы какой способ используете чаще всего? Пишите в комментарии 👇
✍️ @React_lib
Наверняка каждый из нас сталкивался с мучительными попытками организовать удобный менеджмент форм. Хочется, чтобы всё было понятно, компактно и легко поддерживаемо. Вот пара рекомендаций:
1️⃣ React Hook Form — сейчас это самый популярный способ работы с формами. Отличная производительность, минимальное количество ререндеров и простая интеграция с валидацией.
2️⃣ Formik — проверенная годами библиотека, немного проигрывает в скорости, но выигрывает по удобству работы с комплексными формами и кастомными решениями.
Мой личный совет: используйте React Hook Form для небольших и средних проектов. Если же требуется высокая кастомизация и много логики, Formik остаётся отличным вариантом.
А вы какой способ используете чаще всего? Пишите в комментарии 👇
✍️ @React_lib
Сегодня хочу поделиться с вами простым, но часто необходимым при работе приёмом: созданием и использованием кастомного хука
Вот базовая реализация хука
Разбор ключевых моментов:
1️⃣ useRef для флага
Если компонент размонтируется до того, как придёт ответ от сервера, вызов
2️⃣ Состояния
Вынесли все три состояния в хук — теперь в компоненте не нужно повторять одно и то же. Достаточно будет написать:
3️⃣ Параметр
Если
4️⃣ Обработка ошибок
Мы сразу проверяем
Теперь пример использования хука в компоненте:
Плюсы такого подхода:
* Меньше дублирования кода. Вместо того чтобы копипастить один и тот же
* Централизованная логика. Если понадобится добавить, скажем, кеширование или отмену запроса через AbortController, меняем только внутри
* Чистый код в компонентах. Компонент сосредоточен на отображении, а все детали работы с сетью спрятаны в хук.
Советы по улучшению:
* Можно расширить хук, чтобы принимать не только
* Добавить параметр
* Использовать
useFetch
для загрузки данных. Часто в React-компонентах мы дублируем один и тот же код: ставим загрузку, устанавливаем состояние для data
, error
и loading
, пишем useEffect
, чтобы делать вызов API, очищаем эффекты… Всё это можно обобщить в одном месте и переиспользовать во множестве компонент.Вот базовая реализация хука
useFetch
:
import { useState, useEffect, useRef } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// Чтобы избежать обновления стейта после размонтирования компонента
const isMounted = useRef(true);
useEffect(() => {
// При монтировании флага меняются
isMounted.current = true;
// Начинаем загрузку
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`Ошибка ${response.status}`);
}
return response.json();
})
.then(json => {
if (isMounted.current) {
setData(json);
setLoading(false);
}
})
.catch(err => {
if (isMounted.current) {
setError(err.message);
setLoading(false);
}
});
// Очистка: помечаем, что компонент размонтирован
return () => {
isMounted.current = false;
};
}, [url]);
return { data, loading, error };
}
Разбор ключевых моментов:
1️⃣ useRef для флага
isMounted
Если компонент размонтируется до того, как придёт ответ от сервера, вызов
setState
внутри промиса может вызвать утечку памяти и предупреждение React. Флаг isMounted.current
помогает проверить, что компонент ещё жив.2️⃣ Состояния
data
, loading
, error
Вынесли все три состояния в хук — теперь в компоненте не нужно повторять одно и то же. Достаточно будет написать:
const { data, loading, error } = useFetch('https://api.example.com/posts');
3️⃣ Параметр
url
в массиве зависимостейЕсли
url
меняется, хук автоматически запустит новую загрузку.4️⃣ Обработка ошибок
Мы сразу проверяем
response.ok
, иначе бросаем исключение, и в .catch
устанавливаем error
.Теперь пример использования хука в компоненте:
import React from 'react';
import useFetch from './hooks/useFetch';
function PostsList() {
const { data: posts, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts');
if (loading) {
return <div>Загрузка...</div>;
}
if (error) {
return <div>Ошибка: {error}</div>;
}
return (
<div>
<h2>Список постов</h2>
<ul>
{posts.map(post => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.body}</p>
</li>
))}
</ul>
</div>
);
}
export default PostsList;
Плюсы такого подхода:
* Меньше дублирования кода. Вместо того чтобы копипастить один и тот же
useEffect
в десятке компонентов, просто импортируем useFetch
.* Централизованная логика. Если понадобится добавить, скажем, кеширование или отмену запроса через AbortController, меняем только внутри
useFetch
.* Чистый код в компонентах. Компонент сосредоточен на отображении, а все детали работы с сетью спрятаны в хук.
Советы по улучшению:
* Можно расширить хук, чтобы принимать не только
url
, но и опции fetch
(метод, заголовки и т.п.).* Добавить параметр
deps
(зависимости), чтобы перезапускать запрос не только при изменении URL, а при любой другой переменной.* Использовать
AbortController
, чтобы отменять запросы при новых вызовах или при размонтировании:useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(/* ... */)
.catch(err => {
if (err.name === 'AbortError') return;
// обработка других ошибок
});
return () => controller.abort();
}, [url]);
* Можно внедрить кеширование: сохранять результаты предыдущих запросов в объекте и отдавать сразу, если URL повторяется.
В итоге кастомный хук
useFetch
— это простой и мощный инструмент, который сделает ваш код чище и убережёт от типичных ошибок при работе с асинхронными запросами.✍️ @React_lib
💻 Хотите освоить основы веб-разработки с нуля? Откройте для себя важнейшие инструменты HTML
На открытом вебинаре вы подробно разберетесь:
▸ С основными HTML-тегами.
▸ Научитесь применять их атрибуты для стилизации и функциональности.
▸ Мы покажем, как правильно структурировать контент с использованием семантической разметки.
▸ Что поможет вам улучшить SEO и доступность веб-страниц.
🔹 Вы узнаете, как создавать веб-страницы, которые не только выглядят красиво, но и эффективно работают на поисковики и доступны для пользователей с ограниченными возможностями.
📅 Урок 17 июня в 19:00 МСК проходит в преддверие старта курса «Fullstack Developer», все участники получат скидку 5% на обучение по промокодуFULLSTACK_6
🔴 Регистрация открыта: https://vk.cc/cMKubO
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
На открытом вебинаре вы подробно разберетесь:
▸ С основными HTML-тегами.
▸ Научитесь применять их атрибуты для стилизации и функциональности.
▸ Мы покажем, как правильно структурировать контент с использованием семантической разметки.
▸ Что поможет вам улучшить SEO и доступность веб-страниц.
🔹 Вы узнаете, как создавать веб-страницы, которые не только выглядят красиво, но и эффективно работают на поисковики и доступны для пользователей с ограниченными возможностями.
📅 Урок 17 июня в 19:00 МСК проходит в преддверие старта курса «Fullstack Developer», все участники получат скидку 5% на обучение по промокоду
🔴 Регистрация открыта: https://vk.cc/cMKubO
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Понимание React Fiber: как он улучшает производительность рендеринга
React Fiber — это основное обновление, представленное в React 16, которое кардинально изменило способ работы с обновлениями UI, заметно повысив скорость и отзывчивость приложений. Ранее React выполнял все обновления синхронно, из-за чего при крупных изменениях интерфейс мог «подвисать». Fiber решает эту проблему, разбивая рендеринг на мелкие фрагменты, эффективно планируя их выполнение и позволяя браузеру оставаться отзывчивым.
🔑 Главные выводы:
• Инкрементный, асинхронный рендеринг вместо монолитных обновлений
• Приоритезация задач: важные обновления обрабатываются в первую очередь
• Поддержка Concurrent Mode и Suspense
• Преимущества работают «из коробки» на React 16+
Что такое React Fiber?
Это новый reconciler в React, заменивший старый «стековый» алгоритм.
Старый reconciler: синхронный, блокирует UI при большом числе изменений.
Fiber-reconciler: разбивает работу на мелкие, прерываемые задачи — UI остаётся плавным.
Как Fiber улучшает производительность
⌛ Time Slicing (инкрементный рендеринг)
Fiber делит рендеринг на крошечные задачи, выполняемые между фреймами анимации, чтобы не блокировать основной поток.
⚡ Приоритезация обновлений
Сначала обрабатываются срочные задачи (например, ввод пользователя), менее важные откладываются до «паузы» браузера.
🤝 Concurrent Mode
Позволяет приостанавливать, возобновлять и отменять нерелевантные задачи, сохраняя интерфейс отзывчивым.
Ключевые фичи Fiber
* Улучшенный reconciler: минимизирует количество операций с DOM
* Планирование задач: плавный UX при множестве одновременных обновлений
* Concurrent Mode и Suspense: асинхронная загрузка без «заморозок» UI
Пример на React 18: useTransition
Советы по оптимизации
• Используйте
• Lazy-загрузка и code-splitting с
• Windowing для длинных списков (библиотеки `react-window`)
• React Profiler для поиска узких мест
React Fiber автоматически ускоряет ваши приложения на React 16+, делая интерфейс плавным и отзывчивым. Воспользуйтесь преимуществами инкрементного рендеринга и конкурентных режимов, чтобы ваши пользователи получили лучший опыт.
https://blog.openreplay.com/understanding-react-fiber-improves-rendering-performance/
✍️ @React_lib
React Fiber — это основное обновление, представленное в React 16, которое кардинально изменило способ работы с обновлениями UI, заметно повысив скорость и отзывчивость приложений. Ранее React выполнял все обновления синхронно, из-за чего при крупных изменениях интерфейс мог «подвисать». Fiber решает эту проблему, разбивая рендеринг на мелкие фрагменты, эффективно планируя их выполнение и позволяя браузеру оставаться отзывчивым.
🔑 Главные выводы:
• Инкрементный, асинхронный рендеринг вместо монолитных обновлений
• Приоритезация задач: важные обновления обрабатываются в первую очередь
• Поддержка Concurrent Mode и Suspense
• Преимущества работают «из коробки» на React 16+
Что такое React Fiber?
Это новый reconciler в React, заменивший старый «стековый» алгоритм.
Старый reconciler: синхронный, блокирует UI при большом числе изменений.
Fiber-reconciler: разбивает работу на мелкие, прерываемые задачи — UI остаётся плавным.
Как Fiber улучшает производительность
⌛ Time Slicing (инкрементный рендеринг)
Fiber делит рендеринг на крошечные задачи, выполняемые между фреймами анимации, чтобы не блокировать основной поток.
⚡ Приоритезация обновлений
Сначала обрабатываются срочные задачи (например, ввод пользователя), менее важные откладываются до «паузы» браузера.
🤝 Concurrent Mode
Позволяет приостанавливать, возобновлять и отменять нерелевантные задачи, сохраняя интерфейс отзывчивым.
Ключевые фичи Fiber
* Улучшенный reconciler: минимизирует количество операций с DOM
* Планирование задач: плавный UX при множестве одновременных обновлений
* Concurrent Mode и Suspense: асинхронная загрузка без «заморозок» UI
Пример на React 18: useTransition
import { useTransition } from 'react';
function FilterList({ items }) {
const [filtered, setFiltered] = useState(items);
const [isPending, startTransition] = useTransition();
const handleChange = e => {
const q = e.target.value;
startTransition(() => {
setFiltered(items.filter(item => item.includes(q)));
});
};
return <input onChange={handleChange} placeholder="Фильтр…" />;
}
Советы по оптимизации
• Используйте
React.memo
и useMemo
для предотвращения лишних перерисовок• Lazy-загрузка и code-splitting с
React.lazy
и Suspense
• Windowing для длинных списков (библиотеки `react-window`)
• React Profiler для поиска узких мест
React Fiber автоматически ускоряет ваши приложения на React 16+, делая интерфейс плавным и отзывчивым. Воспользуйтесь преимуществами инкрементного рендеринга и конкурентных режимов, чтобы ваши пользователи получили лучший опыт.
https://blog.openreplay.com/understanding-react-fiber-improves-rendering-performance/
✍️ @React_lib
У вас есть шанс освоить профессию с нуля и работать с современными технологиями!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Как анимировать появление компонентов в React с помощью Framer Motion. Это один из тех инструментов, который делает твой интерфейс живым, без особых усилий.
🎬 Пример анимации при маунте:
Используй его просто как обёртку:
✨ Где использовать?
🔘Модалки
🔘Всплывающие подсказки
🔘Новые элементы списка
🔘Контент, который появляется после загрузки
Такая анимация делает взаимодействие с интерфейсом приятнее, особенно если тебе важна микроанимация и внимание к деталям. Framer Motion — мощный, но можно начать с малого.
✍️ @React_lib
🎬 Пример анимации при маунте:
import { motion } from 'framer-motion'
const FadeIn = ({ children }: { children: React.ReactNode }) => (
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
{children}
</motion.div>
)
Используй его просто как обёртку:
<FadeIn>
<Card>Контент</Card>
</FadeIn>
✨ Где использовать?
🔘Модалки
🔘Всплывающие подсказки
🔘Новые элементы списка
🔘Контент, который появляется после загрузки
Такая анимация делает взаимодействие с интерфейсом приятнее, особенно если тебе важна микроанимация и внимание к деталям. Framer Motion — мощный, но можно начать с малого.
✍️ @React_lib
🔧 Шпаргалка по базовым компонентам React
✍️ @React_lib
// Импорт 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