Перейти к основному содержимому

React — хуки, состояние и формы


useState

const [count, setCount] = useState(0);

<button onClick={() => setCount((c) => c + 1)}>{count}</button>

setCount планирует обновление и перерисовку. Форма setCount(c => c + 1) безопасна, если подряд несколько обновлений. State в React иммутабелен: вместо arr.push(x) создавайте новый массив.


useEffect

Побочные эффекты после рендера: запросы, подписки, синхронизация с DOM.

useEffect(() => {
document.title = `Счёт: ${count}`;
}, [count]);
ЗависимостиПоведение
[count]При смене count
[]Один раз после монтирования
нет массиваПосле каждого рендера (осторожно)

Очистка:

useEffect(() => {
const id = setInterval(tick, 1000);
return () => clearInterval(id);
}, []);

Бесконечный цикл — частая ошибка: useEffect без deps вызывает setState → снова effect.


useRef и useContext

useRef — mutable ящик без перерисовки (DOM-узел, таймер):

const inputRef = useRef(null);
useEffect(() => inputRef.current?.focus(), []);
return <input ref={inputRef} />;

useContext — данные без props drilling:

const ThemeContext = createContext('light');
const theme = useContext(ThemeContext);

Для глобального state чаще Zustand/Redux; Context — тема, locale, auth.


События

<button onClick={() => setCount(c => c + 1)}>+</button>

React использует SyntheticEvent и делегирование на корень. e.preventDefault() в формах отменяет отправку по умолчанию.


Контролируемые формы

Значение поля = state:

const [text, setText] = useState('');

<input
value={text}
onChange={(e) => setText(e.target.value)}
/>

Несколько полей — один объект:

const [form, setForm] = useState({ name: '', email: '' });
const handleChange = (e) => {
const { name, value } = e.target;
setForm((prev) => ({ ...prev, [name]: value }));
};

Сложные формы — React Hook Form, Formik + Zod.


Другие хуки

useReducer удобен, когда логика state похожа на конечный автомат. useMemo и useCallback кэшируют вычисления и ссылки — имеет смысл только после замера в Profiler. useLayoutEffect срабатывает до отрисовки браузером; на практике нужен редко.

ХукКогда пригодится
useReducerМного связанных переходов state
useMemoДорогое вычисление на каждом рендере
useCallbackСтабильный колбэк для React.memo
useLayoutEffectСинхронная правка DOM до paint

Связанные материалы

  • 277.md — Router, fetch, lazy, оптимизация
  • 272.md — учебный проект "Заметки"
  • 271.md — таблицы API