Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
React Hooks: полный обзор
Hooks — это функции, которые позволяют использовать state и другие функции React в функциональных компонентах. Они были введены в React 16.8 и стали стандартом разработки, заменив классовые компоненты.
Основные правила использования Hooks
- Вызывай hooks только на верхнем уровне — не в циклах, условиях или вложенных функциях
- Вызывай hooks только в React компонентах — в функциональных компонентах или кастомных hooks
- Используй ESLint плагин для проверки правил
1. useState — управление состоянием
const [count, setCount] = useState<number>(0);
const [name, setName] = useState<string>('');
const [user, setUser] = useState<User | null>(null);
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Счетчик: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
2. useEffect — побочные эффекты
// Запуск при монтировании
useEffect(() => {
fetchData();
}, []);
// Запуск при изменении зависимости
useEffect(() => {
const subscription = subscribe(userId);
return () => subscription.unsubscribe();
}, [userId]);
// Запуск после каждого рендера
useEffect(() => {
document.title = `Вы нажали ${count} раз`;
});
3. useContext — доступ к Context
const ThemeContext = createContext<'light' | 'dark'>('light');
function MyComponent() {
const theme = useContext(ThemeContext);
return <div className={theme}>Контент</div>;
}
4. useReducer — сложное состояние
type Action = { type: 'ADD'; payload: number } | { type: 'RESET' };
type State = { count: number };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'ADD':
return { count: state.count + action.payload };
case 'RESET':
return { count: 0 };
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>{state.count}</p>
<button onClick={() => dispatch({ type: 'ADD', payload: 1 })}>
+1
</button>
</div>
);
}
5. useCallback — стабилизация функций
const handleClick = useCallback(() => {
doSomething(a, b);
}, [a, b]);
// Или с useCallback и зависимостями
const memoizedCallback = useCallback(
(x: number) => x * 2,
[]
);
6. useMemo — мемоизация значений
const expensiveValue = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);
// Пример: вычисление отфильтрованного списка
const filteredUsers = useMemo(() => {
return users.filter(u => u.role === selectedRole);
}, [users, selectedRole]);
7. useRef — ссылки на DOM и значения
function TextInput() {
const inputRef = useRef<HTMLInputElement>(null);
const handleClick = () => {
inputRef.current?.focus();
};
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>Фокус на input</button>
</>
);
}
// Сохранение счетчика между рендерами
function Timer() {
const countRef = useRef(0);
useEffect(() => {
const interval = setInterval(() => {
countRef.current++;
}, 1000);
return () => clearInterval(interval);
}, []);
}
8. useLayoutEffect — синхронные побочные эффекты
// Вычисляется ПОСЛЕ рендера, но ДО отображения на экране
useLayoutEffect(() => {
const height = element.clientHeight;
setPosition(height);
}, []);
9. useDebugValue — отладка кастомных hooks
function useCustomHook() {
const [value, setValue] = useState(0);
useDebugValue(value > 10 ? 'High' : 'Low');
return [value, setValue];
}
10. useId — генерация уникальных ID
function Form() {
const emailId = useId();
const passwordId = useId();
return (
<>
<label htmlFor={emailId}>Email</label>
<input id={emailId} type="email" />
<label htmlFor={passwordId}>Пароль</label>
<input id={passwordId} type="password" />
</>
);
}
11. useTransition — управление переходами
function SearchUsers() {
const [input, setInput] = useState('');
const [results, setResults] = useState<User[]>([]);
const [isPending, startTransition] = useTransition();
const handleSearch = (value: string) => {
setInput(value);
startTransition(async () => {
const data = await searchAPI(value);
setResults(data);
});
};
return (
<div>
<input value={input} onChange={(e) => handleSearch(e.target.value)} />
{isPending && <p>Загрузка...</p>}
<ul>
{results.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
</div>
);
}
12. useDeferredValue — отложенное значение
function App() {
const [input, setInput] = useState('');
const deferredInput = useDeferredValue(input);
return (
<>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<ExpensiveList query={deferredInput} />
</>
);
}
13. Кастомные Hooks
function useWindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
const handleResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return size;
}
// Использование
function MyComponent() {
const { width, height } = useWindowSize();
return <div>Размер: {width}x{height}</div>;
}
14. useFetch — запросы к API
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => { setData(data); setIsLoading(false); })
.catch(err => { setError(err); setIsLoading(false); });
}, [url]);
return { data, error, isLoading };
}
// Использование
function UsersList() {
const { data: users, isLoading } = useFetch<User[]>('/api/users');
return isLoading ? <p>Загрузка...</p> : <div>{/* render users */}</div>;
}
Таблица основных Hooks
| Hook | Назначение | Пример |
|---|---|---|
| useState | Состояние | const [count, setCount] = useState(0) |
| useEffect | Побочные эффекты | useEffect(() => {}, [deps]) |
| useContext | Доступ к Context | const theme = useContext(ThemeContext) |
| useReducer | Сложное состояние | const [state, dispatch] = useReducer(...) |
| useCallback | Стабилизация функций | const fn = useCallback(() => {}, [deps]) |
| useMemo | Мемоизация | const val = useMemo(() => {}, [deps]) |
| useRef | Ссылки | const ref = useRef(null) |
| useLayoutEffect | Синхронные эффекты | useLayoutEffect(() => {}, []) |
| useId | Уникальные ID | const id = useId() |
| useTransition | Управление переходами | const [isPending, startTransition] = useTransition() |
Best Practices
- Не вызывай Hooks условно — всегда на верхнем уровне
- Указывай правильные зависимости в массиве deps
- Создавай кастомные Hooks для переиспользуемой логики
- Используй useCallback и useMemo для оптимизации производительности
- Комбинируй Hooks для создания сложной логики