fa
Feedback
React

React

رفتن به کانال در Telegram

Подборки по React js и все что с ним связано. По всем вопросам @evgenycarter

نمایش بیشتر
2 681
مشترکین
اطلاعاتی وجود ندارد24 ساعت
-27 روز
-1530 روز
آرشیو پست ها
React
2 681
Возможно, вам не нужен useEffect (версия с ref‑колбэками) В React хук useEffect часто используют для выполнения кода после монтирования компонента: подписки, измерения DOM-элементов, вызовы API и т. д. Но в некоторых случаях — особенно когда нам нужно только получить доступ к DOM-элементуuseEffect оказывается избыточным. Что предлагают вместо useEffect? Ref-колбэки. Вместо того чтобы ждать монтирования и использовать useEffect, можно передать функции-колбэку ссылку (ref). Этот колбэк автоматически вызовется, когда элемент появится или исчезнет в DOM. Когда использовать? - Для измерения DOM (размеры, позиция). - Для инициализации библиотек, которые работают с элементом. - Для управления фокусом. Если нужно реагировать на изменения состояния или выполнять сложные сайд-эффекты — тогда useEffect остаётся правильным выбором. ✍️ @React_lib

React
2 681
💪 Хотите работать в финтехе? Освойте Solidity! 👉 Востребованное обучение для разработчиков с опытом программирования от год
💪 Хотите работать в финтехе? Освойте Solidity! 👉 Востребованное обучение для разработчиков с опытом программирования от года, которые хотят получить навыки написания кода и аудита безопасности, чтобы попасть в одну из самых перспективных и высокооплачиваемых сфер IT. Освойте разработку децентрализованных приложений на профессиональном уровне всего за 5 месяцев на онлайн-курсе «Solidity Developer» от OTUS! Забудьте о скучном обучении — здесь вас ждут настоящие челленджи и нестандартные практические решения. А еще крутые проекты для портфолио! 👉 Пройдите вступительные тест для оценки подходит ли вам курс: https://vk.cc/cNUydi 🎁 Получите welcome скидку для успешное прохождение теста. Подробности уточняйте у менеджера. Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

React
2 681
📊 Tremor — готовые React-компоненты для дашбордов. Tremor предлагает более 35 настраиваемых и доступных компонентов React дл
📊 Tremor — готовые React-компоненты для дашбордов. Tremor предлагает более 35 настраиваемых и доступных компонентов React для создания информационных панелей и современных веб-приложений. Создан на основе Tailwind CSS и Radix UI. https://github.com/tremorlabs/tremor ✍️ @React_lib

React
2 681
⚛️ Как я ускоряю загрузку React-приложения с помощью динамического импорта Сеqxfc покажу вам простой, но эффективный способ у
⚛️ Как я ускоряю загрузку React-приложения с помощью динамического импорта Сеqxfc покажу вам простой, но эффективный способ ускорить загрузку React-приложения — динамический импорт компонентов. Особенно это полезно для ленивой загрузки тяжёлых страниц или модалок, которые не нужны сразу при старте. Вот базовый пример:

import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <div>
      <h1>Главная страница</h1>
      <Suspense fallback={<div>Загрузка...</div>}>
        <LazyComponent />
      </Suspense>
    </div>
  );
}
🧠 Что происходит: - HeavyComponent не загружается сразу при запуске. - Он подгрузится только тогда, когда понадобится. - Это уменьшает размер первоначального бандла и ускоряет первый рендер. 📌 Совет: Используй ленивую загрузку для: - страниц внутри роутинга (React Router + lazy) - редко используемых компонентов (например, SettingsModal) - тяжёлых графиков, таблиц, дашбордов 🔥 Бонус: Если хочешь ещё тоньше контролировать загрузку, подключи React Loadable или @loadable/component, которые дают больше гибкости и SSR поддержку. А вы используете ленивую загрузку в своих проектах? Делитесь кейсами 👇 ✍️ @React_lib

React
2 681
⚡️Хотите научиться писать надежные тесты для React-приложений и улучшить свои навыки в тестировании? Присоединяйтесь к открыт
⚡️Хотите научиться писать надежные тесты для React-приложений и улучшить свои навыки в тестировании? Присоединяйтесь к открытому уроку «Тестирование React-приложений с помощью React Testing Library» 23 июля в 20:00 МСК! Разберем: - Основы React Testing Library (RTL): философию и ключевые принципы. - Разницу между RTL и Enzyme, и почему RTL — лучший выбор. - Как тестировать рендеринг, события, асинхронный код и кастомные хуки. Это отличная возможность перед стартом курса «React.js Developer» от OTUS. Все участники получат скидку на обучение и полезные материалы для дальнейшего изучения. 👉Регистрация открыта: https://vk.cc/cNTB9v Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

React
2 681
Секреты React-разработки. Создай React-портфолио с нуля шаг за шагом 👉 Полный цикл разработки: от первой строки кода до деплоя 👉 Создаём современный и динамичный сайт на React 👉 Полное руководство (4 часа 42 минуты) Сегодня я собрал в одном видео весь процесс создания портфолио на React с нуля! 🎥 В этом выпуске мы пройдём все этапы: от вёрстки и компонентов до анимации, переключения тем и финального деплоя. 💡 Что вы узнаете в этом видео: 🔹 Разработка структуры портфолио: создаём секции Home, About, Skills, Services, Portfolio, Clients, Contact. 🔹 Работа с React-компонентами: используем useState, useEffect, props и массивы данных. 🔹 Добавление анимации с Motion: оживляем интерфейс и создаём плавные переходы. 🔹 Переключение тем (светлая/тёмная): реализуем через useState и сохраняем в LocalStorage. 🔹 Динамическое меню и кнопка "Вверх": улучшаем навигацию и пользовательский опыт. 🔹 Деплой на Netlify: публикуем проект и делаем его доступным онлайн. ⏱️ Таймкоды: 00:07 — Обзор проекта - что мы будем разрабатывать в React 00:35 — Настройка окружения перед началом работы в React 15:53 — Создаём структуру проекта и компоненты 25:10 — Импортируем и подключаем картинки в проект 31:09 — Создаём компонент Header с меню навигации 57:50 — Разрабатываем секцию Home в React 01:05:05 — Создаём секцию About с данными о разработчике 01:13:30 — Добавляем секцию Skills с анимацией и эффектами 01:31:01 — Переходим к блоку Work Experience: оформление и логика 01:36:02 — Создаём секцию Services: карточки услуг и стили 02:02:49 — Разрабатываем секцию Portfolio с проектами 02:19:29 — Добавляем блок Next Project для перелистывания работ 02:24:35 — Создаём секцию Our Clients с отзывами и логотипами 02:44:38 — Разрабатываем секцию Contact с формой обратной связи 02:58:10 — Исправляем баг: убираем скролл при открытии мобильного меню 03:01:57 — Добавляем плавное появление popup в секции Portfolio 03:04:10 — Создаём секцию Footer с контактами и ссылками 03:22:00 — Добавляем кнопку "Вверх" для удобной навигации 03:28:33 — Реализуем переключение тем (светлая/тёмная) с сохранением 03:38:51 — Анимация элементов с помощью библиотеки React Motion 03:43:56 — Разбираем работу Motion: ключевые атрибуты и настройки 03:45:22 — Выносим анимацию в отдельный файл для удобства 04:19:07 — Обзор будущих проектов, которые можно реализовать 04:37:53 — Финальный деплой проекта на Netlify 04:42:23 — Всем мира и добра! 🚀😊 источник ✍️ @React_lib

React
2 681
Правило ESLint для обнаружения избыточного состояния в React ✍️ @React_lib

React
2 681
🧠 Зачем нужен React Query и как он меняет подход к загрузке данных Привет! Сегодня я хочу рассказать вам о библиотеке, которая стала для меня must-have в любом проекте на React — React Query. Если вы всё ещё пишете useEffect + fetch + useState, чтобы загрузить данные, ловите инсайт: это можно делать проще и мощнее. Вот чем React Query реально помогает: ✅ Автоматический кеш: данные не перезагружаются каждый раз при переходе между страницами. ✅ Повторные запросы при восстановлении соединения или фокусе окна. ✅ Мутации (POST, PUT и т.д.) с оптимистичным обновлением UI. ✅ Умное управление состояниями: isLoading, isError, data, refetch — всё под рукой. ✅ Простая интеграция с TypeScript. Пример использования:

const { data, isLoading, error } = useQuery({
  queryKey: ['users'],
  queryFn: () => fetch('/api/users').then(res => res.json())
});
🔥 Всё, никакого useEffect! А самое крутое — когда ты добавляешь бесконечный скролл или пагинацию — React Query делает это почти без боли. Если ещё не пробовал — обязательно покрути. Это прям реальный буст продуктивности. Пользуешься ли ты React Query? Или у тебя другой фаворит — SWR, TanStack Query, Apollo? Давай обсудим 👇 ✍️ @React_lib

React
2 681
🔥9 полезных функций и хуков, которые пригодятся продвинутому React-разработчику для управления состоянием, оптимизацией и архитектурой компонентов 1. useDebounce Позволяет "отложить" значение — полезно для ввода/поиска.

import { useEffect, useState } from 'react';

export function useDebounce<T>(value: T, delay = 300): T {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debounced;
}
2. usePrevious Возвращает предыдущее значение пропа или стейта.

import { useRef, useEffect } from 'react';

export function usePrevious<T>(value: T): T | undefined {
  const ref = useRef<T>();
  useEffect(() => {
    ref.current = value;
  }, [value]);
  return ref.current;
}
3. useOnClickOutside Закрытие модалок, дропдаунов при клике вне.

import { useEffect } from 'react';

export function useOnClickOutside(ref: React.RefObject<HTMLElement>, handler: () => void) {
  useEffect(() => {
    const listener = (e: MouseEvent) => {
      if (!ref.current || ref.current.contains(e.target as Node)) return;
      handler();
    };
    document.addEventListener('mousedown', listener);
    return () => document.removeEventListener('mousedown', listener);
  }, [ref, handler]);
}
4. useIsMounted Помогает избежать обновления состояния после размонтирования.

import { useEffect, useRef } from 'react';

export function useIsMounted() {
  const ref = useRef(false);
  useEffect(() => {
    ref.current = true;
    return () => { ref.current = false; };
  }, []);
  return ref;
}
5. useEventCallback Запоминает последнюю версию колбэка без повторного рендера.

import { useRef, useCallback } from 'react';

export function useEventCallback<T extends (...args: any[]) => any>(fn: T): T {
  const ref = useRef(fn);
  ref.current = fn;
  return useCallback((...args: any[]) => ref.current(...args), []) as T;
}
6. useAsync Асинхронный вызов с контролем загрузки, ошибок и результата.

import { useState, useCallback } from 'react';

export function useAsync<T>(asyncFn: () => Promise<T>) {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<T | null>(null);
  const [error, setError] = useState<unknown>(null);

  const run = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const result = await asyncFn();
      setData(result);
    } catch (e) {
      setError(e);
    } finally {
      setLoading(false);
    }
  }, [asyncFn]);

  return { loading, data, error, run };
}
7. useLocalStorage Простой хук для хранения данных в localStorage.

import { useState, useEffect } from 'react';

export function useLocalStorage<T>(key: string, initial: T) {
  const [value, setValue] = useState<T>(() => {
    const json = localStorage.getItem(key);
    return json ? JSON.parse(json) : initial;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue] as const;
}
8. useMediaQuery Работа с медиа-запросами в React без CSS.

import { useEffect, useState } from 'react';

export function useMediaQuery(query: string): boolean {
  const [matches, setMatches] = useState(() => window.matchMedia(query).matches);

  useEffect(() => {
    const media = window.matchMedia(query);
    const listener = () => setMatches(media.matches);
    media.addEventListener('change', listener);
    return () => media.removeEventListener('change', listener);
  }, [query]);

  return matches;
}
9. useToggle Бинарный переключатель состояния (on/off).

import { useCallback, useState } from 'react';

export function useToggle(initial = false) {
  const [state, setState] = useState(initial);
  const toggle = useCallback(() => setState(prev => !prev), []);
  return [state, toggle] as const;
}
✍️ @React_lib

React
2 681
🚀 Как ускорить загрузку React-приложения? 5 реальных советов Сегодня покажу, как я оптимизирую загрузку фронтенда в продакше
🚀 Как ускорить загрузку React-приложения? 5 реальных советов Сегодня покажу, как я оптимизирую загрузку фронтенда в продакшене. Это помогает не только SEO, но и удерживает пользователя, который мог бы уйти, не дождавшись загрузки. Вот 5 проверенных приёмов: 1. Code Splitting (разделение кода) Используйте React.lazy и Suspense, чтобы грузить компоненты только при необходимости. Особенно полезно для роутинга. 2. Tree shaking Убедитесь, что сборщик (Webpack, Vite) удаляет неиспользуемый код. Проверь, чтобы библиотеки импортировались модульно (import { Button } from 'lib', а не всё подряд). 3. Оптимизация картинок Используйте современные форматы (WebP, AVIF) и lazy загрузку изображений, чтобы не тянуть весь хлам сразу. 4. Минификация и сжатие Включите GZIP или Brotli на сервере. Также обязательно минифицируйте JS/CSS. 5. Critical CSS и SSR/SSG Подумайте об использовании Next.js или аналогов. Они помогают загрузить только нужный CSS и HTML прямо на старте, особенно полезно для первых 3 секунд. ❓А какие техники используете вы, чтобы ускорить загрузку? ✍️ @React_lib

React
2 681
Как frontend-разработчику получить оффер в Bigtech? Ты вроде бы уже не джун, но всё равно чувствуешь, что топчешься на месте?
Как frontend-разработчику получить оффер в Bigtech? Ты вроде бы уже не джун, но всё равно чувствуешь, что топчешься на месте? Рынок перегрет, требований всё больше, а откликов — всё меньше? На собесах валят на алгоритмах или просят "нарисовать" архитектуру, как будто ты ведущий. При этом вокруг кто-то постоянно получает офферы в Яндекс или VK, а у тебя не получается даже дойти до финального этапа? Хочется стабильности, интересных задач и наконец-то попасть в сильную команду...
Меня зовут Тихон, привет! Я — действующий Frontend-разработчик и ментор. Помогаю устроиться на хорошие позиции в Bigtech и сопровождаю на испытательном сроке.
В своем канале: 👉 публикую видео с решением задач, которые прямо сейчас дают крупные компании на собеседованиях 👉даю примеры по прохождению собеседований 👉разбираю резюме и докручиваю резюме подписчиков 👉и просто создаю дружелюбное, комфортное сообщество, где коллеги всегда готовы подсказать и поддержать 🎁В закрепе тебя ждёт подборка из 60 задач, которые сейчас дают на собеседованиях Яндекс, Т-Банк и другие крупные IT игроки. Подписывайся и получай максимум пользы, а нас уже больше 2000 🤓: https://t.me/+ESzP3DJQxqs5MmIy Реклама, ИП Галактионов Тихон Витальевич, инн: 771618975809, erid: 2W5zFFv9N4G

React
2 681
🔧 Шпаргалка по базовым компонентам 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

React
2 681
Как анимировать появление компонентов в React с помощью Framer Motion. Это один из тех инструментов, который делает твой инте
Как анимировать появление компонентов в React с помощью Framer Motion. Это один из тех инструментов, который делает твой интерфейс живым, без особых усилий. 🎬 Пример анимации при маунте:

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
2 681
😎 Хотите стать Fullstack-разработчиком и развиваться в IT? У вас есть шанс освоить профессию с нуля и работать с современным
😎 Хотите стать Fullstack-разработчиком и развиваться в IT? У вас есть шанс освоить профессию с нуля и работать с современными технологиями! 💻На курсе «Fullstack Developer» вы научитесь создавать фронтенд и бэкенд приложений, работать с React, TypeScript, Node.js, PostgreSQL и многим другим. Мы обучаем с нуля, шаг за шагом — от верстки до серверной части. 💪 В результате обучения у вас будут 3 проекта в портфолио, которые можно использовать на собеседованиях, а также актуальные знания, которые соответствуют требованиям современного рынка. Все уроки проводятся опытными практиками, а диплом OTUS ценится среди крупнейших IT-компаний. ❗️Набор на курс закрывается, осталось всего несколько мест! Оставьте заявку и получите скидку на обучение по промокоду FULLSTACK_6 : https://vk.cc/cMVa1T Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

React
2 681
Понимание React Fiber: как он улучшает производительность рендеринга React Fiber — это основное обновление, представленное в
Понимание 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

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

React
2 681
💻 Хотите освоить основы веб-разработки с нуля? Откройте для себя важнейшие инструменты HTML На открытом вебинаре вы подробно
💻 Хотите освоить основы веб-разработки с нуля? Откройте для себя важнейшие инструменты HTML На открытом вебинаре вы подробно разберетесь: ▸ С основными HTML-тегами. ▸ Научитесь применять их атрибуты для стилизации и функциональности. ▸ Мы покажем, как правильно структурировать контент с использованием семантической разметки. ▸ Что поможет вам улучшить SEO и доступность веб-страниц. 🔹 Вы узнаете, как создавать веб-страницы, которые не только выглядят красиво, но и эффективно работают на поисковики и доступны для пользователей с ограниченными возможностями. 📅 Урок 17 июня в 19:00 МСК проходит в преддверие старта курса «Fullstack Developer», все участники получат скидку 5% на обучение по промокоду FULLSTACK_6 🔴 Регистрация открыта: https://vk.cc/cMKubO Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

React
2 681
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

React
2 681
Сегодня хочу поделиться с вами простым, но часто необходимым при работе приёмом: созданием и использованием кастомного хука 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, чтобы отменять запросы при новых вызовах или при размонтировании:

React
2 681
🔥 Сегодня расскажу о том, как грамотно управлять состоянием форм в React Наверняка каждый из нас сталкивался с мучительными
🔥 Сегодня расскажу о том, как грамотно управлять состоянием форм в React Наверняка каждый из нас сталкивался с мучительными попытками организовать удобный менеджмент форм. Хочется, чтобы всё было понятно, компактно и легко поддерживаемо. Вот пара рекомендаций: 1️⃣ React Hook Form — сейчас это самый популярный способ работы с формами. Отличная производительность, минимальное количество ререндеров и простая интеграция с валидацией. 2️⃣ Formik — проверенная годами библиотека, немного проигрывает в скорости, но выигрывает по удобству работы с комплексными формами и кастомными решениями. Мой личный совет: используйте React Hook Form для небольших и средних проектов. Если же требуется высокая кастомизация и много логики, Formik остаётся отличным вариантом. А вы какой способ используете чаще всего? Пишите в комментарии 👇 ✍️ @React_lib

React
2 681
Как создать свой кастомный хук usePrevious для хранения предыдущего значения пропсов или стейта в компонентах React. В реальн
Как создать свой кастомный хук 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