Всем привет! Наверняка многие уже видели анонсы React 19 и нового хука use(). Идея выглядит красиво: загружаем промис прямо в компоненте, без useEffect и useState. Но меня как человека, который пережил эпоху componentWillReceiveProps и контекст-массакров, терзают смутные сомнения. Серверные компоненты + use() — это мощно, но на клиенте всё может пойти не так гладко, особенно если забыть про Suspense или начать использовать хук в циклах. Как вам фича? Уже пробовали в pet-проектах или уже в бою? Интересно услышать реальные кейсы: где use() реально упростил код, а где создал новые проблемы с дебагом. И главный вопрос — не станет ли это очередным «серебряным пулей», которую потом будут проклинать новички? Лично я пока осторожен, но очень хочу пощупать новый API в деле.
Слушайте, я, конечно, больше по бэкенду, но когда вижу, как фронтендеры радостно натягивают `use()` на каждый чих, у меня чешется рука открыть `perf` и показать им, где зимуют лишние аллокации. Да, это избавляет от проп-дриллинга, и для читаемости — плюс. Но вы забываете главное правило: любой новый инструмент — это не повод забыть о жизненном цикле. `use()` в цикле или внутри условного рендера — это не «новая фича», это просто способ получить нестабильное состояние, которое вы будете потом неделю отлаживать с `React.StrictMode` в зубах. Если вы не понимаете, когда контекст реально обновляется, а когда вы просто дергаете сервер на каждый рендер — вы не спасаетесь, вы создаете себе проблемы на ровном месте.
Так что мой вердикт: инструмент рабочий, но только для тех, кто уже умеет в голове держать модель реактивности целиком. Для остальных — это как дать ребенку бензопилу: вроде и дерево спилит, но половину забора заодно. Проп-дриллинг — это боль, но предсказуемая боль. А вот «магическое» разрешение промисов в рендере — это уже не боль, это анестезия, после которой вы просыпаетесь в канаве с кучей сайд-эффектов. Так что да, поддерживаю, но с оговоркой: сначала почините свой `memo`, потом уже лезьте в `use()`.
Согласен на все сто, и особенно про «бензопилу» — метафора в точку. Я как раз недавно переписывал с `use()` один легаси-компонент, где была выборка данных по клику. Поначалу выглядело красиво: никакого `useEffect` и лишних стейтов. Но как только добавили параллельные переходы между табами, `use()` в условном блоке превратил рендер в лотерею — промис разрешался уже после того, как пользователь переключился на другую вкладку, и мы получали мерцание с данными от предыдущего запроса. Пришлось откатывать назад и оборачивать всё в нормальный `useTransition` + явную отмену через `AbortController`.
Поэтому мой тезис такой: `use()` — это не замена управлению состоянием, а скорее сахар для чтения контекста, который уже гарантированно синхронизирован. Использовать его для асинхронных данных стоит только там, где источником является серверный компонент или кэш, который React сам контролирует. В остальных случаях — это просто способ перенести сложность из пропсов в неявные зависимости, которые потом ищут через `git blame`. Так что да, инструмент мощный, но правило «сначала пойми, потом используй» тут работает жёстче, чем с хуками. Иначе вместо спасения от проп-дриллинга получите новый вид боли — «промис-дриллинг» с дебагом в `React DevTools`.
👍 1
Ох, касатик, ну вы и спросили... Сижу вот, чай с баранками пью, на ваши новомодные хуки поглядываю. Проп-дриллинг, говорите? Милок, я помню времена, когда пропсы из одного модуля в другой передавались через пару десятков строк кода, и это называлось «архитектурой». А теперь у вас `use()` — и все, счастье пришло. Только вот смотрю я на это дело и думаю: вы хоть сами поняли, что асинхронщину в компонент теперь можно засунуть, как конфетку в карман, а потом удивляться, почему оно перерисовывается не тогда, когда надо, а когда промис соизволит резолвнуться? Это ж не спасение, это ж как гаечный ключ вместо молотка — вроде и бьет, но по пальцам больно.
Но, с другой стороны, если аккуратно, с умом, да с теми же `Suspense` — может и выгорит. Только вы там, главное, не забывайте про старый добрый `useMemo` и про то, что `use()` — это не магия, а просто обертка над контекстом. А то начнете сейчас каждый чих через него прокидывать, а потом удивитесь, что у вас все приложение в бесконечный лоадер превратилось. Ну да ладно, вам виднее, я-то больше по ассемблеру, там все просто: взял регистр, записал, прочитал. Никаких тебе подводных граблей... почти.
👍 1
use() действительно не магия, а скорее сахар над контекстом и промисами. Вопрос в том, что люди часто путают «можно» и «нужно». Проп-дриллинг — это боль, но он хотя бы явный. use() убирает визуальный шум, но добавляет скрытые зависимости от порядка рендера и Suspense. Один неверный кейс — и получаешь неявный фолбэк вместо ожидаемого контента.
Мне ближе подход, когда use() используется точечно, для чтения контекста, который реально нужен глубоко в дереве. Для асинхронных данных лучше оставить старый добрый data-фетчинг на уровне роутера или сервера. А если уж хочется экспериментов — стоит сначала почитать исходники реализации. Там видно, что это не магия, а просто обертка над thenable. Но, как обычно, дьявол в деталях: кеширование, повторные вызовы, лимит на количество промисов в компоненте. Так что да, спасение для аккуратных, нога для остальных.