Стоит ли использовать useQuery в своих проектах?
Vložit
- čas přidán 27. 07. 2024
- Что вы знаете о react-query? Это один хук useQuery? Он еще какой то хук предоставляет? Почему эту либу устанавливает каждый 10-ый проект? Попробуем разобраться с этими вопросами в новом видео
Статья: tkdodo.eu/blog/why-you-want-r...
Демо: github.com/Sin9k/react-query-...
ТГ канал - t.me/it_sin9k
Поддержать Айти Синяка можно здесь:
CZcams: / @it-sin9k
boosty: boosty.to/sin9k
Patreon: / itsin9k
00:00 Анонс темы
00:44 Что такое react-query?
01:50 Изучаем статью
05:57 Изучаем демо
08:52 26 разделов
11:20 Почему react-query популярен
12:39 Итоги
Подписаться на канал: / @it-sin9k
Twitter: / it_sin9k
На заре этой лимбы ее философия была такой(насколько я помню) - мы даем вам возможность делать легкие запросы и мутации, а также решаем проблему порой сложной работы со стейтом в виде Redux, сложный стейт-менеджер вам просто не нужен, вы все оч удобно можете брать с сервера "налету" и парсить data в любом месте страницы/компонента. Стоит оговориться , что разработчики скорее всего подразумвали не все проекты, а те в которых действительно нет архисложной системы хранения данных и работы со стейтом. Например тот же самый список статей, лента новостей, какой-нибудь ресурс для обучения с тестами и все в таком роде.
Да, useQuery успешно справляется с той же самой пагинацией и кеширование выглядит очень привлекательно, да там простые запросы и простые мутации. Но какой в этом смысл если при некоторых простых с первого взгляда, и посмею сказать, не редких сценариях нужно задумываться как решить проблему? Рыть доку в поисках компромиссов или придумывать какие-то неочевидные кастомные решение - сама суть простоты useQuery по мне так теряется.
Вот вам простой пример. У меня есть массив [{name: "Max"}, {name: "Roy"}, {name: "Helen"}, {name: "Rid"}] . Я хочу сделать пагинацию - по 2 namе на страничке. Вроде все просто - делай query запрос, устанавливай пагинацию и все. НО а что если по ТЗ у меня стоит задача, сделать элементы перетаскиваемыми? То есть я хочу, чтобы на второй странице первым шел Rid, а затем Helen?Мы можете мне ответить, что юзай useMutation и все, но тут я поменяю этот массив на сервере, что неприемлемо.
По сути в такой реализации нужно опять создавать некий промежуточный Стейт с использованием useContext/ useDispatch/useState или где-то хранить эти данные. А если еще по условию будет задача добавить фильтрацию или сортировку уже перетасканных name, то вообще черт ногу сломит как это адекватно реализовывать. Подчеркну, что решение это проблемы есть, но оно , на мой субъективный взгляд, идет в разрез со всей философией которую закладывали в useQuery. Поэтому считаю, что на этапе архитектурного планирования проекта нужно продумывать, где использовать это решение: понимать что за проект, будет ли обрастать жирком, кто будет писать, как быстро нужно запустить. Полагаю , что полностью заменить классические запросы + Стейт получится далеко не на всех пролётках, а делать микс из классического скейта и query не всегда есть смысл, это как изобретать велосипед. Однако на страницах где много данных и нужен Кеш я с удовольствием бы использовал данную любу, уж больно все хорошо она делает)
Вот такие мысли по этому поводу, спасибо, поправляйте меня если я не прав. Будьте здоровы и счастливы
Спасибо за подробный комментарий) запиню даже его)
Я бы с удовольствием оспорил текущий аргумент но ютуб мне не даёт)
Элементарная задача, через useQueryClient меняй данные) Такое чувство что комент джун писал...
Просто не путай сетевой кэш и состояние приложения, и не смешивай их.
@@iwmatt я написал такой же большой развёрнутый ответ) getQueryData setQueryData
Спасибо за разбор! Как всегда на высоте. Хотелось бы еще сравнение с rtk-query и в целом куда вся индустрия идет в плане хранилищ
спасибо! Потихоньку на все обзоры запилим) и rtk-query тоже)
было бы интересно послушать про SWR
Запилим) не вопрос)
поддержу
технология сдохла
Покупать лично билет на конфу это как ходить в кинотеатр, чтобы посмотреть рекламу
та не, не перекручивай, наоборот - ходить на бесплатную конфу - это посмотреть рекламу. Конфу что-то должно спонсировать, чтобы там что-то было. И если спонсируют ее организаторы полностью, то понятно, что то будет реклама.
Или кому-то поприколу тратить тысячи долларов на конфу, куда не надо покупать билеты?)
По-моему TanStack Query - это тот случай, когда «Мне надо делать функционал, я не хочу думать о инфраструктуре». Просто берёшь инструмент и делаешь. Когда-нибудь никогда можно будет переписать на оптимизированный вариант
Привет. Честно говоря удивлён читать такое. О какой инфраструктуре не хотите думать когда используете реакт-квери ? =) Вы чертовски правы, берешь инструмент и делаешь. Просто делаешь, красиво, быстро и изящно. И ничего не надо будет переделывать, если сделали как раз таки думая о грамотной архитектуре проекта. ;)
А почему бы и не подумать и сделать хорошо?
То что с React query нельзя сделать хорошо это заблуждение
@@d0paminer а, что есть такие, кто думает, что это заблуждение? Сразу же понятно что React query это лучше решение для работы с асинхронным кодом, тот же функционал например на сагах написать это в десятки раз больше кода
Мне одному кажется сам дизайн управления данными из хуков (api компонентов реакта) сомнительным? На рабочих проектах всегда было удобнее поддерживать те, где data-layer был привязаны к роутам (ну или хотя бы сгруппированы в компоненте по роуту в одном месте) и не зависели от рендеров компонентов. В реакте и так сложно следить за выполнением кода в компонентах, а использование хуков с бизнес-логикой еще сильнее это усложняет.
Хочется увидеть есть ли конкретные причины перейти от redux-toolkit и RTK Query к tanstack query.
разве RTK Query не redux включающий в себя toolkit? К тому же даже в документации ртк пишут, что они вдохновлялись подходом tanstack query, он же бывший react-query (затрахали со своими переименованиями, хер разберешь где что).
@@true227 Да, RTK Query для хорошей работы с апи, совмещён с редаксом. Но вот Tanstack сам по себе, поэтому к нему нужен отдельный стейт менеджер для ui/бизнес состояний , поэтому обычно интересна именно связка стейт менеджера и либы для запросов. Мне интересно стоит ли переходить от редакса и RTK/RTK Query на другой стейт менеджер и tanstack, так ли это обоснованно?
Привет Саш, спасибо за видео. Я бы сказал что сила этой либы в синхронизации сервер-состояния с клиентом. useQuery это лишь единственный хук для GET запросов, а сколько еще нужно учитывать в большом приложении? Мутация и инвалидация кеша - это самое больное на клиенте и react-query даёт простые инструменты для его управления. Для того, чтобы миграция на следующие версии пакетов была менее болезненной, useQuery и подобное обычно оборачивают в wrapper (адаптер). В итоге изменения происходят только в нём, и не приходится что-либо менять в местах использования. Немного уточнений на счет redux не забывай что для полной функциональности берётся весь toolkit, в котором до сих пор много бойлер плейт кода для простых задач. React-query как по мне стал неотъемлемой частью экосистемы. А его интеграция с @tanstack/react-router отдельная тема для видео. Удачи!
А вы используете активно его сейчас у себя на проекте? какие кейсы очень удобно покрывает?
@@it-sin9k У нас весь апи обёрнут react-query. Даже не знаю сколько костылей пришлось бы придумывать в тех или иных ситуациях используя что-то другое) Да всё по-сути. Обычные crud стали еще проще все нужные запросы лежат в кастомных хуках которые можно переиспользовать по всему приложению. Та же инвалидация, вот получаешь ты список чего-то. Затем добавляешь в него новый item, твоя mutateAsync функция вызывается из любого места компонента, которая использует те же ключи для инвалидации запроса когда новый item добавлен в БД.
const { mutateAsync } = useCreateClusterDevice(id, clusterId);
try {
await mutateAsync(payload);
toast.success('Global params added successfully');
navigate(pageUrl);
} catch (e) {
toast.error('Error adding adding global params');
}
в свою очередь mutate по окончанию инвалидирует первоночальный список синхронизируя серверное сотояние или нет если добавить onError.
export function useCreateClusterDevice(elevationId, clusterId) {
const queryClient = useQueryClient();
return useMutation(
(payload) => createClusterDevice(elevationId, clusterId,
{
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [clusterDevices] });
},
}
);
}
Работа с callback-ами становится удовольствием, мне не надо вручную лезть в стор. Заметь, что оба хука используют статические queryKey для синхронизации и динамические их параметров. Т.е. любой новый запрос с другими Id взаимозаменяет данные в кеше, мне приходится при этом делать - ничего.
В общем нужен конкретный кейс, ну или созвон с кейсами)
@@it-sin9k staleTime для запроса в настройках. Добавив пару секунд ты сократишь кол-во запросов в несколько раз, в некоторых ситуациях критично. Представь что у тебя две страницы А и Б. Обе первым запросом получают данные getItemById(itemId), почему они обе делают одинаковые запросы? Да просто потому что на обе страницы можно попасть через URL, но на станицу Б можно попасть по навигации из А. Так вот если ты в А только что получил данные и переходишь на Б в "staleTime" нового запроса не будет getItemById() просто достанет данные из кеша потому что не прошло staleTime и они считаются свежими. Сколько костылей с таймерами и очисткой надо написать чтобы добиться решения такой простой задачи. По-моему много.
@@it-sin9k всего и не перечислишь, это лишь простые примеры. А сколько ситуаций было когда что-то делаешь и благодаришь Таннера за то что react-query существует)
Я описал три простых примера но yt решил, что достаточно показать один, ну да ладно)
Только вчера начал изучать useQuery, и тут видео Синяка)
Можно сказать сэкономил время))
Не использовал useQuery, но отметил бы несколько моментов из видео:
5:20 - автор лукавит, он упаковал запрос и его обработку в отдельную функцию loadBookmarks, которая не является универсальной. Поэтому получается, что строки её кода нужно учитывать при сравнении количества строк.
7:35 предполагаю, что данные не стали undefined. Хук обратился к кэшу второй страницы, которого не было, поэтому в данные вернулся undefined. Аналогично, когда автор вернулся на первую страницу, хук посмотрел кэш первой страницы, увидел, что данные есть и вернул их. После этого данные перезапросились в лучших традициях swr
По поводу первого момента, я сравнивал прод код один, с продовским кодом альтернативным. useQuery под капотом тоже включает тьму кода.
Второй момент, вы хорошо объяснили. Спасибо!)
@@it-sin9k не согласен,. useQuery - это универсальное решение, его код можно будет поменять везде по проекту, а вот специфическую функцию loadBookmarks так использовать вряд ли получится. Поэтому useQuery не включается в объём кода, а loadBookmarks стоит включить. Надеюсь, что смог донести свою мысль правильно 😂
Спасибо! Много слышал про него но ни разу не использовал, возможно в каких-то ситуация и стоило, но зачастую просто потратил два часа и все работает
Спасибо за видео, очень полезный и актуальный вопрос подсветил)
для себя давно решил, что мобХ покроет все нужды)
Отличный ролик. Интересная тема для роликов - разбор популярных библиотек
Спасибо! Буду и дальше продолжать разбирать некоторые либы)
Мне понравилась либа , слезли с редакса + саги , намного меньше кода стало в проектах. На счет раздутости хука согласен , много свойств с него никогда не использовал .
спасибо за комментарий! а можете рассказать, какие хук и как используете? собираю статистику) можете здесь (github.com/Sin9k/react-query-demo) даже issue открыть и загрузить какой пример кода) интересно посмотреть)
@@it-sin9k404 😢
В принципе РТК решает те же самые проблемы но в базе имеет редакс - по этому покрывает кучу кейсов кросс-компонентного использования. И так же на выходе в реакт компоненте маленький хук с удобной апишкой + огромный пул возможностей по управлению кешами? параметрами запроса? интерсепторами и т.п.
Да, действительно в React БЫЛА проблема с загрузкой данных для страниц. Отсутствие нормальной загрузки данных привязанной к навигации, а не к рендеру каких-то компонентов. Выход react router v6 исправил эту долгую проблему и добавил loaders. Концепция которая всегда существовала в Angular (resolve) и Vue (beforeRouteEnter). В сочетании с конструкцией + для многих случаев можно вообще избавиться от стор мэнеджера. Ну а если все таки нужно шарить данные, то можно в loader интегрировать Zustand или MobX и вызывать actions от туда. Далее те же actions могут вызываться из компонент на действия пользователя для изменения и обновления данных. И никаких useEffect в компонентах))
Использую RTK Query, кажется покрывает все кейсы которые только можно, очень похож на react-query, но по ощущениям более мастабируемый.
Забавный факт, меня очень бесило, что начальное состояние возваращало undefined и я всячески пытался установить initialState, но спасибо видео, узнал что это часть best practices))
я сначала думал, что это видос про хук для работы с query-параметрами в url
Использцю TanStack Query для замены Rtk (для меня query намного лаконичнее). По сути кеш является стейтом и есть куча методов работы с ним. Чего стоит только инвалидация query по ключу, которую очень удобно использовать внутри мутаций.
Спасибо за комментарий! А можете привести рабочие кейсы где прям круто работает useQuery?
Так это всё и в RTK есть. Вообще я пока не вижу разницы между RTK и TanStack Query и не понимаю зачем они с переизобретают колесо один в один
@@adeptiworks Вообще-то это RTK переизобретают колесо, т.к. копировали react-query. Который изначально копировал apollo, но для работы с обычным REST API без graphql.
Что значит переизобретают? Эффект обратный. useQuery 5 лет, в то время у rtk были только слайсы, экшоны и редюсеры.
не уверен, но по-моему в RTK query в отличие от react query (tanstack) нельзя заинвалидировать кэш из другого (createApi) по тэгу т.е. декларативным способом как в рамках одного Api, а в react query это делается просто по ключу (что поудобнее чем в RTK query ).
Все на скачки, пацаны
А в Ангуляре придумали для миграций схемы) Добрые авторы сами их пишут, чтобы как можно безболезненнее все обновилось автоматически :)
Больше года юзаю эту декларативщину с кешированием и ретраем из коробки. Вначале было прикольно, но когда бизнес логика усложнилась, стало не удобно, все эти юз квери и rtkq сильный оверхед, не гибко, а иногда критично если сроки поджимают. На уровне концепции идея заманчивая, но жизнь сложнее. На пет проекте юзаю reatom v3, скоро будет v4 с более простым апи, очень нравится
там есть похожая на useQuery история это reatomResource, борьба с race condition на уровне Abort controller, ретраи тоже есть если надо, много чего еще
спасибо что поделились опытом!) это очень ценно)
Использовал rtkquery для создания веб-чата, показался очень гибким, все хотелки бизнеса закрыл (кроме infinity scroll)
@@Stat3mach1n3 базовый функционал не сложно написать, но описывать сложную бизнес логику из цепочек запросов становится не удобно, иногда нужно что-то пробросить, обработать как-то иначе и в этом проявляется не гибкость юз квери. Конечно идеальных инструментов не существует, надо знать где что юзать. Но на большой проект я бы не тащил юз квери
Интересное видео
В общем-то лучшим решением будет написать свои кастомные функции на валидации ошибок и запросов, а насчёт кэша просто в стейт менеджере переименовать data в dates (нерды, не грызыте меня, я знаю, что нет множественной формы) и просто в ключи добавлять такие же ключи, как и в реакт квери?
"data" is a plural noun-it is the plural form of the noun "datum"
@@frusen_sol ну, я и имел ввиду, что от данных нельзя плюрал сделать, ибо оно не считабельное, но не знал, что оно от datum идёт)
На нескольких проектах стоит реакт куери, оч удобно
Каждому по своему писать тоже не очень идея, надо бы этот кейс унифицировать для всех, чтобы все одинаково как писали так и юзали. Возможно надо придумать новую абстракцию, которая оборачивает все так чтобы все пользовались одинаково
Мне кажется, что react-query - это еще одна попытка решить вечную проблему с отправкой запросов, хранением состояния, обработкой ответов, хранением данных.
Раздутое апи в виде хуков с длинным названием увеличивает бандл. И это проблема, если для вас это очень критично.
Но на мой взгляд, это пока единственное хорошее решение, которое позволяет хоть как- то стандартизировать этот момент.
Из плюсов я вижу: кэширование, возможность управлять состоянием запроса: лоадинг, фетчинг, отмена и т.д., управлять временем хранения данных, рефетчить данные из любого места приложения, не беспокоиться о повторной загрузке данных, если query вызывается в нескольких частях приложения.Ну и всякий сахар в виде retry, infiniteQuery, disabling/pausing.
Также у них есть очень полезные девтулзы, которые позволяют смотреть и управлять состоянием запросов, чтобы не через console.log.
Момент на 9:16. Можно поставить опцию, чтобы data не обнулялась, до завершения fetching.
Спасибо за подробный комментарий! А можете поделиться интересными кейсами использования? или сколько в итоге из API набора у вас на проекте используется) хотелось бы лучше понять как его используют на проектах)
Ещё шортполлинг удобный, можно вообще про него не думать, он просто работает и отключается при необходимости одной строчкой.
@@it-sin9k
useQuery, useMutation, useQueryClient, QueryClient, QueryClientProvider, useInfiniteQuery.
Что касается самого useQuery. Понятное дело, все опции и свойства хука не используем.
Из часто используемых. data, isLoading, isFetching, isPending, error, refetchOnWindowFocus, retry, refetchOnMount, refetchOnReconnect, placeholderData, staleTime, enabled.
Не нравится, конечно, вечное переосмысливание того, как проблема должна решаться. Видимо, это неизбежно в результате эволюции пакета. К 5 версии, как будто, изменения стали менее заметными. Но с react-router, конечно, ничто не сравнится.
Хочу спросить у знающих. Пользуюсь редаксом и давно посматриваю на query библиотеки. Вопрос такой: есть например данные по языку данных, которые мы запросили с бэка, положили в стор и используем по всему проекту. Как такое провернуть через тот же useQuery?
Привет, в твоем кейсе достаточно во всех местах где нужны данные вызывать один и тот же useQuery, он сам будет доставать данные из кэша. Либо есть вариант, где нибудь ближе к корню проекта один раз вызвать useQuery, положить данные в контекст и затем из него доставать там где нужно.
@@Trolas97 так вот как это работает, спасибо)
Почитай доку, на все про все пару часов
Одна из самых крутых фишек за которую я полюбил react-query. Это то что в queryKey можно положить всё что угодно. Даже объект который библиотека, перед инвалидацией кэша, сравнивает по содержимому а не по ссылке.
Так же библиотека отлично вписывается в микрофронтовую архитектуру. Приходится меньше думать о том как связывать микрофронты с какими то общими данными.
Спасибо за комментарий :)
При микрофронтах я так понимаю все фронты связываются через единый react-query контекст. Точно так же работает и Redux. Если контекст один то и все микрофронты будут использовать один стор :)
реально запрос каждый раз на сервак летит, даже если в кэше есть эти данные? а он прерывается как-то или что?
Запрос летит или не летит зависит от параметров заданных вами в QueryCliebt. Отмена запросов происходит через AbortController .
Можно конечно же настроить это дело) чтобы не летел) но тогда есть риск показать не релевантные данные)
@@it-sin9kну есть же данные которые редко обновляются. Да и время кэширования можно какое-то маленькое задать. Допустим пару минут и все просто и красиво. А когда сам добавляешь какую-то новую сущность можно сделать инвалидацию кэша кэша чтобы в следующий раз когда понадобятся эти данные либа отправила запрос на бэк
5:37 очевидно же почему :) Стало модным притягивать за уши баги и сложности другого подхода дабы максимально превознести свою либу.
а в танстек квери есть какая нибудь штука, которая может смержить результат нескольких кастомных хукво? например если я в компоненте делаю
const postsData = usePosts();
const usersData = useUsers();
и мне нужно показать страницу только тогда, когда оба хука загрузят данные. можно использовать useQueries, но там я не могу использовать кастомные хуки.
я пока только придумал сделать типо вот такой хук:
function useMergedQueriesData(queriesData) {
const isLoading = queriesData.some(queryData => queryData.isLoading);
const hasError = queriesData.some(queryData => queryData.error);
return { isLoading, hasError }
}
и делать потом const { isLoading, hasError } = useMergedQueriesData([postsData, usersData]);
но проблема в том, что вычисления в some каждый раз будут делаться, и в useMemo не обернуть, потому что postsData и usersData не постоянные, если только делать
const deps = useMemo(() => [postsData, usersData], [postsData.isLoading, postsData.error, usersData.isLoading, usersData.error]), но это гемор
а зачем вообще мержить результаты? Почему просто не вывести лоадер при isLoadingPosts || isLoadingUsers
@@kiritushka представь что тебе нужно сделать 5 запросов, и на нескольких страницах
@@monterio1234 опишите подробнее ситуацию свою когда для отображения контента нужно сделать аж 5 запросов, мне сложно такое представить
@@kiritushka например есть список элементов, и у каждого элемента есть id из других списков, типо зависимости. Напоимер есть список users, у которых есть их посты и их проекты в полях postsIds, projectIds, которые из отдельных ручек надо загрузить. Помимо этого на странице юзеров может быть еще какая нибудь информация, которая может с других ручек загружаться, которая с юзерами может быть вообще не связана, например документация
@@monterio1234 мне кажется тут архитектурно неправильно построено, если мы отображаем список пользователей, но вся необходимая информация для списка должна приходить в одном запросе. Ваша ситуация очень странная, для одного списка делается несколько запросов. Если же так действительно нужно и по другому никак, то я бы сделал один хук типа useUsers и использовал бы useQueries с его специальным методом combine для объединения данных. Если же на одной странице помимо списка пользователей есть что то еще, то лоадеры не должны объединяться в один, на том месте где пользователи - свой лоадер, в другом - другой. Еще лучше использовать скелетоны.
Блин, я просто в mobx асинхронные методы с axios пишу. Как-то смотрел документацию про tanstack query, так не понял зачем так усложнять всё.
В том и прикол, что вы видимо не поняли в чем суть. До этого так же использовал МОбх, а теперь на старом проекте ищу время чтобы его выпилить и сделать по нормальному с react-query. По факту надо научиться мыслить чучуть по другому, отлично от стор ориентированного приложения.
Охрененно мощный и удобный инструмент, который также можно подружить с Mobx и юзать совместно.
а какие методы вы используете? чисто для загрузки данных?
@@it-sin9k базовый crud, оптимистичные обновления, пагинация , рефетч интервал , удобные рефетчи по ключам. В основном это
Смотрю, что многие отметили слово «скачек». А что не так? Вроде ок
Коммент в закреп 😊
да) видимо люди хотят меня на скачки отправить))
Еще либа обеспечивает дедупликацию запросов и рефетч кверей по ключу после мутаций, что без использования react-query является очередным геморроем похожим на race condition. в целом вроде все в ней прикольно, но вес и избыточная функциональность заставляет задумываться о целесообразности использования
Именно так, в ангуляре нафиг не нужен квери там все из коробки шикарно работает, а вот в реакте сколько лет уже он развивается, но нормальной возможности сделать запрос нету! В 19ой версии будет use хук - может он поможет...
да) я тоже жду анонса 19) чтобы потрогать скорее) большие надежды) но как то неверится)
Вот уже 3ий наверно год как я ушел со стейт менеджеров типа Ридакса и Мобыкса и их мидлов и всяких саг и танков на реакт-квери + контекст. Это сравнимо с тем, что ты шел по грязи и тащил за собой тележку навоза, вонючего такого , тяжелого, а потом в один момент спустился боженька с небес и сказал БРОСЬ ЭТО, ФУ, боже мой. Остаётся одни вопрос, а где вы были раньше... Хотя я знаю где.. Долго расписывать.=) просто "кто-то" известный протолкнул ридакс однажды, а до них ФБ протолкнул ФЛАКС и он по инерции до сих пор оставляет следы =)))))) хотя хуки появились уж пол века назад.
интересные у вас предпочтения) а контекст имеется ввиду react-query провайдер используете или отдельно что то хранить в нем транспортируете?
@@it-sin9k Просто react-context из коробки для хранения каких то общих данных приложения или в модулях для модулей. При этом react-context используется хитро, с так называемыми селекторами, чтобы замена одного свойства в нём не аффектила на всё приложение, а только там где это необходимо.
А ничего что скачивания учитвыают так же и продакшен сборку, каждую сборку в cicd, jenkins и т.д.??
а что с этим не так?
Это либа не нужна если вы используете NextJS, а именно так с реактор и надо делать, потому что серверные компоненты это очень мощная для UI/UX вещь
Вы, походу, ещк джуник без опыта, если пишете такие глупости 😂
Я уже примерно год юзаю react-query, но всё же я старовер, мне rtk-query гораздо больше нравится, тк всё это время я работал с редаксом. Да и порадовала типизация в v5. Но всё ещё необходимо подрубать ky, axios, ect, да ин а сколько понимаю локальный счётчик туда тоже не засунуть, приходится выкручиваться через контекст реакта.
На работе в ряде проектов используется Rtk query. Мне не нравится.
Пока смотрю в сторону Effector. Надо ещё демки сделать с Reatom.
В планах все либы пощупать)
Сейчас в моде Jotai.
Кирилл Мокевнин - один из лучших программистов с которыми я рад знакомству лично. второй в моем списке это Евгений Зайцев
круто) я тоже его почитываю) любопытно пишет)
Использую аналог, useSWR от vercel, скачиваний 1.6млн/нед.
Интересно что ты думаешь об Effector
Давно его запланировал) но пока никак не дойду)
Сложилось впечатление, что автор ролика не особо углубился в эту библиотеку. Почему речь шла только про хук useQuery, где useMutation? Или у вас сайты только на получение данных работают?
Сделал уже 4 проекта с использованием React Query. Теперь в сторону всяких, прости господи, redux, mobx и тд, даже не посмотрю.
По поводу инвалидации - не вижу никаких проблем, вызвал функцию invalidateQueries, передал ключ, который нужно инвалидейтнуть, на этом все....
По поводу data - который стает undefined, есть метод placeholderData - куда можно передать функцию keepPreviousData (которая есть в пакете) и в таком случае, старые данные будут видны до момента получения новых.
можно было бы упомянуть useMutation. Но я и так кажется описывал в достаточно позитивном свете react-query. Идея показать, что кажется он слишком громоздкий для такой мелкой задачи
Сразу видно чела, который работал с либой
вот как раз использую эту шляпу... и реализация двойной (инфинити + постраничка) пагинации это боль
В чем боль то? Меняешь страницу - обновляешь initialPage.
А разве все хуки грузятся на стороне клиента, если используешь лишь useQuery?
не очень понял вопрос. Под фразой грузятся, что вы имеете ввиду?
@@it-sin9k на стороне клиента разве будут грузится всё-всё, что предоставляется библиотекой? Вроде сборщик создаст чанки лишь на основе того, что используется в проекте
@@BlueCell прям все скорей всего не будет, но раз уж мы используем useQuery, то все что для его работы надо тоже потянется, а значит и контекст потянется. А в нем хранится весь state management, а это значит что потянет все это не мало за собой :)
@@it-sin9k ну, как по мне, кеш главная фича либы
Сам TanStack Query говорит, что он не полнотстью заменяет стейт менеджеры общего назначение. А ещё у TanStack сейчас делается свой стейт менеджер
Получается нужно теперь в проекте иметь 2 стейт менеджера?
@@it-sin9k выходит что да, если надобность в другом стейт менеджере есть.
Мне только сейчас попался проект с TanStack Query, до этого использовал RTK Query. В целом RTK Query решает те же проблемы что и TanStack, так что можно обойтись только Редаксом)
Вроде бы все просто и удобно, а шаг в лево/право и начинаются какие то танцы с бубном. особенно больно решать проблемы когда нужно изменить поток данных в архитектуре. Для себя решил что максимум где можно его адекватно юзать, это запросы в справочники для автокомлитов или любой статичной инфы которая не нужна больше нигде. А на крупном проекте все равно все делается через слой модели и апи, а там хорошо работает свзяка центрального хранилища + мидлварина какая нибудь. а те 5 багов что описали в статье, это больше крайность, и пример криворукости того кто такое пишет. И еще задумался, что если для создателей либы такой код это обыденность и их либа решает у себя под капотом ее, то выходит что вокруг нас очень много некомпетентных разрабов, которые не понимают что делают, и не хотят разбираться особо.
в мире много джунов === некомпетентных сотрудников))
лойк
Мнение до просмотра ролика:
Однозначно не стоит. Реакт - библиотека для отрисовки компонентов. В ее задачи не входит Запросы на сервер и манипуляции с данными.
Внедрение работы с данными в жизненный цикл компонента - прямой путь к багам, перегрузки компонента функционалом и прочим плохим вещам
В мире много языков, но это язык фактов
в жц - имеешь ввиду всякие useEffect, useLayoutEffect, правильно понимаю? на обработчик клика допустим фетчинг?
И интересно, Если не секрет, как ты избавляешь компоненты от подобной штуковины? На этапе react-router-dom запросы делаешь? Или при инициализации запросов фетчишь данные? Или мб шину какую-то свою написал, куда из ЖЦ кидаешь триггеры?
и правильно понимаю, что vue и angular могут нормально фетчить, потому что они фреймворки и предоставляют какие-то готовые решения? или там тоже коряво на ЖЦ завязываться?
И каково мнение после просмотра?)
@@notdefined9072 факт остается фактом жнж
> Стоит потратить 2 часа и написать свой хук
Плохой совет, за который можно потом долго расплачиваться
Если беспокоит вес, то возьми swr или альтернативу
> Плохой совет, за который можно потом долго расплачиваться
почему плохой?)
@@it-sin9k велосипеды редко когда бывают чем-то хорошим. При командной разработке преимущество существующих либ в готовой документации, примерах, готовых и удобных решениях, покрывающих самые частые требования к либе.
Зачастую очень сложно предсказать развитие проекта. Если потребуется больше функционала, то у кого-то может появиться желание допилить твой велосипед, а по итогу он превратиться в сложный код, знание которого нужно только конкретно в этом проекте, что затрудняет вход новичков, которым перед использованием нужно преисполниться и смириться. Если при увеличении требований выкидывать велосипед и менять на либу, то время на велосипед изначально было потрачено зря, т.к. прикручивать либу удобнее, чем изобретать свою за 2 часа, за которые должно получится хорошее и удобное решение без проблем с первого раза(звуки недоверия)
Велосипед можно написать, если прям совсем странные требования, безопасники либу запрещают или это свой проект и по приколу. Практически всегда рационально брать готовое решение
@@it-sin9k писать свои велосипеды иногда очень весело не спорю, но всегда надежнее иметь инструмент с документацией и тестами, одобренный большой частью коммьюнити фронта.
у велосипедов, есть как свои преимущества так и недостатки. Недостатки вы хорошо описали. Если будет писать недостаточно опытный разработчик, то с высокой вероятностью это превратиться в месиво.
Но есть и достоинства:
- код не может устареть. Если ваши требования к функционалу не меняются, то и инструмент работает. Нет либы, которую нужно обновлять, читать документацию и делать миграции
- весь код на твоей, стороне и можно запилить вместо кода, который умеет работать со всеми проектами мира, простой код, который умеет работать только с твоим проектом
В итоге всегда нужен баланс:
- писать свой React это глупость
- если все что вы используете из react-query это useQuery, набросайте хук за 2 часа
Для слишком простых задач слишком сложно
Для сложных не дотягивает, аполло в этом случае гораздо выигрешнее
у vue есть vue-api-query, но он и нахер не нужон, если пользовать нормальные стейт менеджеры типа pinia
опробуйте ещё refine
а что это такое?
@@it-sin9k так же как и useSwr это что то похожее на tanstack query, может есть ещё похожие либы, но я пока не узнал о них
@@it-sin9k это аналог useQuery
@@it-sin9k это аналог юзквери
спасибо!) надо познакомиться)
Скачкиии 🏇
Первое состояние undefined это звучит как антипатерн) такая себе идея
на вентилятор наброшу поррасуждать) что в этом плохого?)
@@it-sin9k Возможно немного поторопился с выводом, относительно того как под капотом работает хук useState. Но точно могу утверждать что рантайм js не очень любит когда одному идентификатору присваиваються значения разных типов данных. В данном случае предполагается присвоить сначала значение undefined, потом оно измениться на массив. Связанно это прежде всего с процессом оптимизации и с тем что вызывает процесс де оптимизации нашего кода на уровне движка. Де-оптимизация это то что убивает перфоманс нашего кода наверное больше всего. Кстати есть еще один тип это null, он как раз был придуман для объектов с неопределенной структурой, и на уровне оптимизирующего компилятора не вызывает процесс деоптимизации. Это кстати поэтому и typeof null = «object», а не потому что, как говорят некоторые на собесах, там инженеры ошиблись, а не исправляют, что бы старые сайты работали 😂
да) мне null тоже нравится больше)
@@liganshow есть где прочитать про это? статья или еще что
@@user-bg3hu1oz4y форум разработчиков v8) спецификация ecma)
с 6:55 по 7:35 слабый аргумент, потому что ты просто вынес все в отдельный хук, но все равно сам написал этот код и общее количество строк кода только увеличилось))))
Да вообще странная логика сравнивать код без либы и код с либой. Если смысл либы оптимизировать такие вещи, что вы там ожидаете увидеть? Что станет сложнее?
да) но если задуматься, что мы сравнивали. Ванильный запрос к серверу с useQuery, который включает в себя тоны кода. А мой поинт на протяжении всего видео был, что набросайте свой хук и пере используй его в разных местах. В итоге в месте использования будет 20 строк :)
@@it-sin9k брат в квери фишка в том, что нам не нужно писать лишний код вообще)
@@it-sin9k понятно что самому можно на ваниле все повторить и написать свой квери)
так весь код кем то написан. Либо вами, либо разрабами npm пакетов. Если код писал разраб npm пакета, то он пилил код не под ваши нужды, а под абстрактные требования. А если вы сами, то можете адаптировать сугубо под свои нужды. С другой стороны, код написанный в популярном npm пакете, кажется должен быть более стабильным. Поэтому всегда нужно оценивать, стоит ли брать npm пакет или набросать самому
Разработчикам фичафлаги не сильно то и облегчают жизнь, скорее несут большую нагрузку
конечно это впервую очередь помогает бизнесу. Но например мы можем мержить в dev недопиленные фичи и не надо висеть отдельно в ветке долго и синкать ее постоянно, пока она не будет идеально запилена. А еще не надо в проде срочно откатывать фичу, если она не взлетела, просто отключаете фича флаг. А / Б тестирование с ними настроить тоже одно удовольствие) Поэтому меня это спасало не раз)
useJQuery()
огонь!)
На 7:28 обман. "Как видите, код с 39 строк уменьшился почти в 2 раза до 20 строк и стал куда читабельнее". Читабельность - это субъективная метрика, так что ее оставим.
Автор не "специально писал плохой код", он писал код, который не предполагает знание и понимание внешних зависимостей кроме useQuery и fetch. В примере на react-query вся логика у нас на глазах, мы видим:
1. Урл куда делается запрос
2. Обработку ошибки
3. Ключи глобального кэша куда складываются результаты запросов
Далее ты приводишь пример якобы "компактного продкашн кода".
1. Он не компактный - В этом коде не 20 строк, урл и обработка ошибок лежат в loadBookmarks, а логика редьюсера в fetchReducer. То есть добавляй к твоим 20 строкам еще loadBookmarks и fetchReducer.
2. Он не продакшн - кэша просто нет и все хранится в локальном состоянии с помощью useReducer. Какова вероятность, что тебе этот запрос понадобится только в текущем компоненте? Какова вероятность, что тебе нужно будет инвалидировать результаты этого запроса из другого компонента? А дедубликация нужна будет? В продакшн проектах все эти проблемы возникают в 100 случаев из 100, а текущий пример никак не решает эти проблемы.
Действительно, это хорошая практика выносить обработку запросов в сервисы, но это никак не связано с примером. На react-query тоже можно было бы вынести обработку ошибок в loadBookmarks и тогда бы там пример вообще был на 6 строчек.
А количество скачиваний отчасти связано с тем, что люди, которые не работали с react, слыхом не слыхивали про tanstack query. А версия для ангуляра вообще появилась только пару месяцев назад, когда в ангуляр подвезли сигналы, так что там и не будет больших цифр.
"Возможно у других фреймворков нет таких проблем с неудобной отправкой запросов" - они есть, точно такие-же. И во vue и в angular люди решают эти проблемы по-старинке с помощью стейт-менеджеров, что превращается в лютый адище.
Совет самому написать useQuery не такой плохой, если тебе не нужен весь этот функционал, то пожалуйста. Просто в этом и смысл был всей статьи, что люди забывают про сложные вещи типа race condition'ов, поэтому, если ты не гуру асинхронного программирования, то велика вероятность, что ты можешь допустить ошибку при написании собственного хука. А если далее он будет использоваться по всему проекту, а тебе вдруг нужно будет добавить в этот хук функционал, которого изначально там не предполагалось (вроде аборт контроллера например), то ты потом замаешься везде это править. А в tanstack-query это есть из коробки (само собой не бесплатно по размеру бандла, но что поделать).
Спасибо за подробный комментарий! Люблю подискутировать на такие темы)
> В этом коде не 20 строк, урл и обработка ошибок лежат в loadBookmarks, а логика редьюсера в fetchReducer. То есть добавляй к твоим 20 строкам еще loadBookmarks и fetchReducer.
Я согласен, что не весь код показал. Вы все верно указали. Но ведь я сравниваю свой код с useQuery, который скрывает в сотни раз больше кода, чем я скрыл) Как по мне именно такое сравнение и честное. У них свой абстракция скрывающая некую логику, у меня своя абстракция скрывающая намного меньше логики. А сравнивать useQuery с кодом, у которого вообще нет никакой абстракции, совсем получается не честно.
> Он не продакшн - кэша просто нет и все хранится в локальном состоянии с помощью useReducer. Какова вероятность, что тебе этот запрос понадобится только в текущем компоненте? Какова вероятность, что тебе нужно будет инвалидировать результаты этого запроса из другого компонента? А дедубликация нужна будет? В продакшн проектах все эти проблемы возникают в 100 случаев из 100, а текущий пример никак не решает эти проблемы.
Тут много моментов:
- А нужен ли вообще кэш в вашем проекте? В моем текущем бизнес напрочь отказался от него и проект много лет в продакшене. Поэтому вполне себе продакшен пример :)
- Допустим нужен. Должен ли быть кэш пере используемым в разных местах? Возможно тоже нет. И достаточно сделать кэш в рамках одного редьюсера
- Допустим вам нужен кэш между разными компонентами. Ну и это вроде как запилить не сложно даже с useReducer или добавить redux или еще что-то. Тут нужно только обсудить какие у вас требования
> "Возможно у других фреймворков нет таких проблем с неудобной отправкой запросов" - они есть, точно такие-же. И во vue и в angular люди решают эти проблемы по-старинке с помощью стейт-менеджеров, что превращается в лютый адище.
тут я не знаю. Но были комменты, что в ангуляре нет с этим проблем
> Просто в этом и смысл был всей статьи, что люди забывают про сложные вещи типа race condition'ов, поэтому, если ты не гуру асинхронного программирования, то велика вероятность, что ты можешь допустить ошибку при написании собственного хука.
Да, но статья не предупреждает о том сколько всего за собой тянет установка этой либы. Как будто установил ее и теперь все твои проблемы решены. Но ведь, чем дальше ты пойдешь с этой либой, тем больше АПИшки и т.д. тебе придется выучить и освоить на практике. Что то же не честно со стороны автора такое писать)
@@it-sin9k > А нужен ли вообще кэш в вашем проекте? В моем текущем бизнес напрочь отказался от него и проект много лет в продакшене.
А как вы без него живете? как решаете проблему с дедубликацией запросов? У вас что никогда нигде не требуется запросить одни и те же данные в разных компонентах?
в большинстве моих проектов, очень важна актуальность данных, чем уменьшение количества запросов. Да и вспомнить не могу, чтобы бизнес это когда то волновало
@@it-sin9k Да, согласен, за useQuery скрыто больше кода, но и в useReducer этот код тоже есть. Думаю было бы максимально честно без выделения loadBookmars. То есть доменный код остался бы в одинаковом состоянии в обоих примерах и сравнивали бы мы только инфраструктурный код.
> А нужен ли вообще кэш в вашем проекте? В моем текущем бизнес напрочь отказался от него и проект много лет в продакшене. Поэтому вполне себе продакшен пример :)
Тут я склоняюсь к тому, что твой проект скорее исключение, чем правило.
> Допустим вам нужен кэш между разными компонентами. Ну и это вроде как запилить не сложно даже с useReducer или добавить redux или еще что-то. Тут нужно только обсудить какие у вас требования
С useReducer этого не запилить, понадобится минимум либо проп-дриллинг и лифт состояния вверх, либо контекст. Но ты сам понимаешь, что тут появляются серьезные вопросы по перформансу, у тебя по-моему даже был видео про это. Redux затягивать - это вообще похороны, у redux'а гораздо больше когнитивной нагрузки за ним, чем у react-query. Для простого переиспользования кэша бэкенда в двух компонентах redux - это дикий оверкилл.
> тут я не знаю. Но были комменты, что в ангуляре нет с этим проблем
Само собой у каждого свое понимание "проблем". В Ангуляре люди в основном используют то, что предоставлено командой ангуляра, а не сторонними библиотеками. Поэтому там чаще всего это встроенный httpClient на rxjs (или сверху еще и обертки в виде стейт менеджеров, ngrx или ngxs - те же самые redux и mobx только профиль). Я работал на ангуляре больше 2 лет, и за это время так и не нашел ни одного решения, которое хотя бы близко подходило к tanstack-query по пользовательскому опыту(да и по опыту разработчика тоже).
> Но ведь, чем дальше ты пойдешь с этой либой, тем больше АПИшки и т.д. тебе придется выучить и освоить на практике
Не вижу в этом проблемы. В этом и сильная сторона react-query: он предоставляет реализацию, которую ты себе представляешь в голове, по дефолту, не заставляя тебя понимать как это все под копотом должно работать. А если ты хочешь изучить это дальше самостоятельно - изучаешь.
Единственное в чем я с тобой согласен насчет "нечестности" статьи, это то, что статья называется "Почему вам НУЖЕН react-query" и дает 5 "багов", из которых критичный и относительно сложный в понимании и предугадывании только первый, а последний вообще не баг и react-query не решается. То есть клик-бейт на лицо.
@@it-sin9k Актуальность данных само собой важна, но react-query не мешает тебе обновлять данные при заходе на страницу. Он предоставляет эту возможность, при этом показывая устаревшие данные (aka паттерн SWR), чтобы пользователь не смотрел на лоадеры (опять же это так работает из коробки и если тебе это не надо - можешь отключить, но опыт пользователя улучшается совершенно без усилий со стороны разработчика).
Так есть же graphql + apollo
Скачек... Режет ухо. Скачиваний )
Я считал что useSWR лучше и популярней
Высер из верселевской пробирки
и до него доберусь как то записать обзор)
Такая гадость, в кеш не залезть, фетчера нет, не трекнуть несколько запросов, кеш не протухает. Жрем этот кактус, на полях переезд на query, а по хорошему все на mobx с DI сделать надо.
@@badcoder1337 вопщем трудности только на некстжс изза отсутствия возможности автоматически фоллбеки делать.
а так узе-свр вещь хорошая и некоторые описанные выше вещи делать позволяет(через мутации)
Что такое DI?
Как фетчер SWR нравится больше. Проще гораздо юзать. Но и функционала меньше
React-query вдохновлялся Apollo, где обязательно нужен был GraphQL, пытаясь скопировать его экспириенс только без самого GraphQL.
Но до магии apollo, конечно, не дотянул, хоть и приблизился.
Потом уже пошли последователи в виде RTK и useSWR.
Вообще не понимаю людей, которые до сих пор юзают redux и какую-нибудь saga, или, упаси господи, thunk. Для меня прям это пещерные люди из 2016 года.
Спасибо за комментарий! А какой в итоге ваш любимый стек?
@@it-sin9k Предпочел бы Apollo, но текущие проекты без graphQl. А так react-query для сетевых запросов и какой-нибудь простенький менеджер глобального состояния типа zustand
Тоже стек интересует)
скачек))
боже зашо такое косноязычие
реально уши режет?) а я когда записывал, думал если буду говорить "скачиваний" то будет совсем занудски) и так канал ботанский))
@@it-sin9k вкусовщина, конечно.
Мне режет, а кто то читает мой комментарий и думает «че докопался, душнила»
Контент в любом случае годный, спасибо за видео!
...че докопался, душнила
@@it-sin9k Люблю нердов, используй скачиваний