Кастомные хуки (Custom Hooks). Создаем свой первый кастомный хук useWindowSize
Сегодня напишем простой, но очень полезный хук -
Мы создадим функцию, которая:
1. Использует
2. Использует
3. Важно: Не забываем удалять обработчик событий (cleanup function), чтобы не нагружать память!
Вот готовый пример. Можете сохранить его в файл
🚀 Как это использовать в компоненте?
Теперь ваш компонент становится чистым и понятным. Никакой лишней логики внутри!
✍️ @React_lib
Сегодня напишем простой, но очень полезный хук -
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
👍3❤1
🚀 Что такое условный рендеринг в React и зачем он нужен?
Если говорить просто, условный рендеринг - это способность вашего React-приложения решать, что именно показывать пользователю в зависимости от определенных условий (состояния, пропсов и т.д.).
Думайте об этом как о "if... else...", но для вашего пользовательского интерфейса (UI).
- ЕСЛИ пользователь вошел в систему, ТО показать компонент
- ИНАЧЕ показать компонент
💡 Для чего он нужен?
Без условного рендеринга все наши приложения были бы статичными. Именно эта концепция делает интерфейс динамическим, "живым" и отзывчивым.
Он нужен буквально повсюду. Вот самые частые примеры:
- Пока идет загрузка данных с сервера: Мы показываем
- Аутентификация: Показываем "Профиль", если
- Обработка ошибок: Если при загрузке произошла ошибка, мы показываем
- Пустые состояния: Показываем "Ваша корзина пуста", если
- Интерактив: Показ/скрытие модальных окон, выпадающих меню или вкладок по клику.
🛠️ Как это сделать?
В React есть несколько популярных способов:
1. Тернарный оператор (
2. Логический оператор "И" (
3. Обычный
Условный рендеринг - это не просто "фича", это сам смысл React. Это то, что позволяет вашему UI реагировать на изменения данных и действия пользователя.
#React #JavaScript #Frontend #Development #ConditionalRendering
✍️ @React_lib
Если говорить просто, условный рендеринг - это способность вашего 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
👍4❤2
🔥 Антипаттерн в 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
👍3