tgoop.com/React_lib/712
Create:
Last Update:
Last Update:
Почему ваш useEffect лишний (и что вместо него)
Сейчас покажу 6 типичных случаев, где useEffect не нужен и только плодит баги и лишние рендеры. Дам короткие «до/после».
1. Вычисляемое из пропсов/стейта
❌ Плохо
const [fullName, setFullName] = useState('');
useEffect(() => { setFullName(`${user.first} ${user.last}`); }, [user]);
✅ Хорошо
const fullName = `${user.first} ${user.last}`;
2. Фильтрация/сортировка списка
❌ Плохо
const [filtered, setFiltered] = useState<Item[]>([]);
useEffect(() => { setFiltered(items.filter(byQuery(query))); }, [items, query]);
✅ Хорошо
const filtered = useMemo(() => items.filter(byQuery(query)), [items, query]);
3. Счётчики/таймеры для UI
❌ Плохо — пишут в стейт каждую секунду, лишний рендер
✅ Лучше — храните в
useRef, рендерите только когда нужно показать новое число:
const tickRef = useRef(0);
useEffect(() => {
const id = setInterval(() => { tickRef.current++; }, 1000);
return () => clearInterval(id);
}, []);
// Когда надо отрисовать — дерните setState из контролируемой точки.
4. Синхронизация формы с данными
❌ Плохо — «заливают» в стейт через эффект
✅ Лучше — передавайте значения как
defaultValue/values в форму или используйте «ключ» для ремонта формы:
<form key={user.id}>...</form>
5. Запросы данных
❌ Плохо — «сами» тащим
fetch в эффект, пишем кэш, статус, отмену✅ Лучше — вынесите в data-layer (например, TanStack Query) или хотя бы в отдельный хук с кэшем и отменой.
6. События окна/документа
Если обработчик не использует реактивные данные — храните его в
useRef и вешайте один раз. Если использует — чаще всего достаточно мемоизировать колбэк и вешать/снимать один раз.
const handlerRef = useRef<(e: KeyboardEvent) => void>(() => {});
handlerRef.current = (e) => { /* читаем актуальные значения из замыканий/рефов */ };
useEffect(() => {
const onKey = (e: KeyboardEvent) => handlerRef.current(e);
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, []);
Мини-чеклист «нужен ли тут эффект?»
- Это побочный эффект вне React (I/O, подписка, таймер, манипуляция DOM)? → Да —
useEffect.- Это чистое вычисление на основе пропсов/стейта? → Нет эффекта, используем выражение/
useMemo.- Можно ли пересчитать при рендере без записи в стейт? → Делайте это.
- Будет ли этот эффект легко зафлапать гонками? → Пересмотрите дизайн.
✍️ @React_lib
BY React

Share with your friend now:
tgoop.com/React_lib/712
