[Эксперимент] useContext + useReducer вместо Redux

  Рет қаралды 11,652

АйТи Синяк

АйТи Синяк

Күн бұрын

Думаю многие видели заголовки: "Context API vs Redux". Сегодня я решил провести очную ставку и написать небольшой экран с использование useContext + useReducer. Результат смотрите в видео!
исходники: github.com/Sin9k/useContextPl...
Поддержать Айти Синяка можно здесь:
KZfaq: / @it-sin9k
boosty: boosty.to/sin9k
Patreon: / itsin9k
00:00 Анонс темы
00:34 Постановка задачи
01:00 Создаем UsersContext
03:05 App.js AddUser.js Users.js
04:02 Двойной Provider
05:10 dispatchUsers костыль
06:00 Подытожим
07:09 Юбилей 10 000 !!!
Подписаться на канал: / @it-sin9k
Twitter: / it_sin9k
________________
Канал о Фронтенде, который хочется порекомендовать (telegram):
t.me/frontendnoteschannel
-------------------------
Данный канал создан для инициирования бесед на различные темы IT сферы (социальные / технические), а также для тех кому короткая видео выжимка статьи, выступления на конференции или же просто личных мыслей, являются более удобным форматом

Пікірлер: 53
@Prog_Ramer
@Prog_Ramer 2 жыл бұрын
1) нет необходимости dispatch тянуть в компонент, если его можно один раз импортировать в файл action'ов (и прописать соответственно в каждой ф-ции экшенов). А в компонент уже импортировать и вызывать сам актуальный action с соответствующими аргументами. Соответственно, всё это обернуть в хуки 2) redux devtools частично можно заменить на use-reducer-logger, который выводит отработанные экшены в консоль кстати, проблема множественного контекста, когда корневой компонент каждый раз оборачивается во вновь созданный провайдер контекста, решается тем, что такой провайдер можно поставить локально на необходимую группу компонентов ниже по дом дереву (не знаю, можно ли так делать в редаксе, не пробовал) спасибо. У вас интересные видео на канале
@it-sin9k
@it-sin9k 2 жыл бұрын
Хорошие комментарии спасибо!)
@rim7avan
@rim7avan 2 жыл бұрын
От бойлерплейта поможет createSlice из инструментария редакс) Видос - топ, особенно костыль понравился)
@AndreyZhukov-iu4ko
@AndreyZhukov-iu4ko 2 жыл бұрын
Мы у себя на проекте использовали контекст для работы с вебсокетами. У нас была интересная задача по получению данных и управлению портативными спектральными анализаторами. Для этого я сделал контекст по прокидыванию функции, которая сэтила уникальный обработчик для каждой страницы, который писался в реф. Сам раньше не особо использовал контекст, но для данной задачи получилось весьма изящно)
@it-sin9k
@it-sin9k 2 жыл бұрын
Интересный кейс, спасибо что делитесь!
@boldureans
@boldureans 2 жыл бұрын
Саш, спасибо за видео. Я считаю что использование контекста оправданно в SaaS приложениях, где нет много стейта на клиенте и вы часто посылаете запросы на бек, он по сути и синхронизирует общее состояние приложения. Скажу про себя мы используем контекст ну и реакт-квери для кеша. Приложение выросло давольно сильно, и пока необходимости для rtk не нашлось)
@it-sin9k
@it-sin9k 2 жыл бұрын
Я честно говоря не до конца понимаю, что такое SaaS приложение :) А насколько ваш подход с контекстом отличается, от того что я смог придумать в этом видео?)
@boldureans
@boldureans 2 жыл бұрын
@@it-sin9k Непонятно куда подевался текст всего моего коммента. В общем там было что использование почти такое же, прелесть в том, что провайдеры можно переписывать на разных уровнях вложенности, как это показано на ссылке снизу)
@c01nd01r
@c01nd01r 2 жыл бұрын
Спасибо за видео. Для оптимизации ре-рендеров через контекст можно использовать react-tracked
@it-sin9k
@it-sin9k 2 жыл бұрын
Не знал такую библиотеку. Даже исходники глянул ее. Спасибо :)
@aleksd286
@aleksd286 2 жыл бұрын
самое лучшее, что сейчас есть это zustand для работы с глобальным стейтом, но нашем большом проекте который мы сейчас с 0 пишем мы используем redux-toolkit (+turborepo, pnpm workspaces, nextjs и тд)
@theDenQ
@theDenQ 2 жыл бұрын
Я думаю, что каждый инструмент, нужно использовать по назначению. Контексты элегантно решают проблему пропс дриллинга, без лишних коннектов. Но заменять ими весь стейт менеджер, так себе идея. Спасибо, за наглядный пример! :)
@it-sin9k
@it-sin9k 2 жыл бұрын
Все верно! Поэтому мы создали еще одно видео! kzfaq.info/get/bejne/l7ZhiJCJtcWcj5s.html
@tIMSjR
@tIMSjR 2 жыл бұрын
Главная проблема контекста в том, что на любой чих в стейте произойдет перерисовка всего дерева компонентов. Потому что в связке контекст+useReducer передается значение стейта, а при использовании редаксе -- инстанс.
@qutbiddinmakhmudov4088
@qutbiddinmakhmudov4088 2 жыл бұрын
Лайк лайк лайк! Прошу сделай видео про react.hydrate. Было бы многим полезно. Спасибо заранее
@it-sin9k
@it-sin9k 2 жыл бұрын
Это целая отдельная тема про SSR и все такое. Нужен целый плейлист :)
@qutbiddinmakhmudov4088
@qutbiddinmakhmudov4088 2 жыл бұрын
@@it-sin9k Ну плейлист так плейлист от меня коммент и лайк к каждому видео и патреон
@Prog_Ramer
@Prog_Ramer 2 жыл бұрын
@@it-sin9k кстати, хорошая идея, если у вас будет время, записать видео по SSR
@ingwarrr
@ingwarrr 2 жыл бұрын
Это ещё что. Настоящие костыли пойдут, когда начнешь писать самодельные асинхронные миддлвары
@it-sin9k
@it-sin9k 2 жыл бұрын
ахахха) надеюсь до такого не дойдет)
@yonebayashi_
@yonebayashi_ 2 жыл бұрын
У редакса же есть redux dev tools плагин для хрома
@mtyEyes
@mtyEyes 2 жыл бұрын
Ничего элегантного у меня нет - контекст юзал только в двух случаях: 1) Когда изменение контекста и так будет приводить к перерендеру всех подписанных компонентов(переключение темы или языка как пример) 2) На прошлой неделе нужно было инициализировать ванильную библиотеку с картами внутри реакт компонента и раздать ее инстанс по окружающим компонентам. Перерендера там нет, а вот получить ссылку просто написав useMapContext() просто и понятно. И либу никакую тянуть не надо
@kostyakozlov5289
@kostyakozlov5289 2 жыл бұрын
что за useMapContext?
@mtyEyes
@mtyEyes 2 жыл бұрын
@@kostyakozlov5289 Просто кастомный хук
@sergeysibara4346
@sergeysibara4346 2 жыл бұрын
Прозвучала интересная фраза - "почти не использую контекст на своих проектах") Было бы интересно узнать, что используете вместо него? На своих проектах если и использую контекст, то только для хранения объекта с ссылками на сторы.
@it-sin9k
@it-sin9k 2 жыл бұрын
а мы как раз следующее видео уже почти смонтировали, на тему "как эффективно использовать context" :)
@kostyakozlov5289
@kostyakozlov5289 2 жыл бұрын
Спасибо огромное за твой контент, хотел задать неколько вопросов (возможно я не в курсе и fiber уже никто не использует, скажите что почитать) Вопрос - прибегает ли react к созданию новых узлов fiber при рендере У себя в видео ты говорил, что React создает при рендере новое дерево (это ведь дерево которое реакт конструирует из узолов называемых fiber?), я читал статью (Max Koretskyi Inside Fiber), в ней он тоже говорил, что реакт создает дерево из узлов fiber, но там он так же упоминал, что узел fiber не создается при кажом рендере снова, а изменяются (но тогда получается, что не остается work in progress Tree --- то есть не с чем провети сравнине) Вопрос - как react пропускает элементы при выполнении рендара? Он делает определенную проверку? Например: при запуске setState от useState, (происходит определенная запись в соответствующий объект fiber с пометкой о том, что нужно выполнить работу, и react бежит по дереву и когда доходит до это пометки он вызывает функцию, которую берет из поля объекта узла fiber, где она записана в поле type), у меня сложилось такое впечатление, что react не может вернуть при вызове самой верхней функции-компонента один связанный результат(дерево) потому, что после вызова createElement от функции-компонента нет никакой ссылки в полученном объекте о возвращенном результате ---- следовательно он где то уже зафиксирован, поэтому (возможно, если следовать моему воображению) когда react начинает вызов нижестоящих функций-компонент (все транспилируется в вызовы craateElement и там), react автоматически создает для каждого узла fiber клон и в него записывает всю новую информацию о каждом элементе, а потом уже сверяет с новым деревом currentTree ) - это просто мое предположение чуть-чуть основанное на информации, которую я где то обрывками находил я просто не понимаю как react собирает информацию об объектах,если вызов console.log(createElement()) от фунции, которая что то возращает (разметку) то мы увиди почти пустой объект, а если вывести console.log(createElement()) от div , который влючает какие либо элемнты, то уже будет информация из этого я пришел к выводу, что она уже где то фиксируется
@it-sin9k
@it-sin9k 2 жыл бұрын
Привет :) задаешь очень хорошие вопросы) некоторые из них я не уверен как точно это работает. Я видел твой предыдущий комментарий. И мне нужно время, чтобы меньше гипотиз выдвигать, а больше фактов :)
@kostyakozlov5289
@kostyakozlov5289 2 жыл бұрын
@@it-sin9kпривет, понял, спасибо ))
@it-sin9k
@it-sin9k 2 жыл бұрын
В общем потратил я какое то время чтобы найти прувы к моим обрывочным знаниям. Идея в том, что все файбер ноды хранятся не деревом, а условно массивом. И когда обходится дерево, указатель на элемент в массиве меняется. Или элементы могут удаляться в середине массива. Таким образом делая workInProgress дерева все что нужно это по указателю достать fiber ноду и доработать ее или заменить на другую. Чтобы подтвердить мои слова, вот отрывок из этой статьи: indepth.dev/posts/1008/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react React processes updates very quickly and to achieve that level of performance it employs a few interesting techniques. One of them is building a linear list of fiber nodes with effects for quick iteration. Iterating the linear list is much faster than a tree, and there’s no need to spend time on nodes without side-effects. А так же вот исходники React, где добавляются элементы в массив и удаляются function push(cursor, value, fiber) { index++; valueStack[index] = cursor.current; { fiberStack[index] = fiber; } cursor.current = value; } function pop(cursor, fiber) { if (index < 0) { { error('Unexpected pop.'); } return; } { if (fiber !== fiberStack[index]) { error('Unexpected Fiber popped.'); } } cursor.current = valueStack[index]; valueStack[index] = null; { fiberStack[index] = null; } index--; }
@19n1ght
@19n1ght 2 жыл бұрын
А почему Вы не использовали useMemo для users and dispatch и не передали его в value провайдера? Если передать массив (как у Вас в самом первом примере), то все дерево будет постоянно повторно рендериться.
@it-sin9k
@it-sin9k 2 жыл бұрын
Хмм, разве есть смысл оборачивать? Единственной причиной рендера этого компонента является изменения в users. Других причин рендера вроде нет. Если даже обернуть в useMemo, вы все равно в зависимости поставите users. Т.е. useMemo будет обновляться в 100% случаев.
@igor_cojocaru
@igor_cojocaru 2 жыл бұрын
@@it-sin9k const [count, setCount] = React.useState(0) const value = React.useMemo(() => { return { count, setCount, } }, [count]) return типа такого должно помочь с лишними рендерами
@it-sin9k
@it-sin9k 2 жыл бұрын
Каким образом оно должно помочь? Единственная причина рендера этого компонента - обновление значения count. Если count изменился тогда и value изменилось. В таком случае и рендеров никаких не избегаем
@kostyakozlov5289
@kostyakozlov5289 2 жыл бұрын
@@it-sin9k я так же сначала тупанул, потом загрузил репозиторий, наставил точек останова и понял, что рендер на этапе отправки action не запускается
@kulakofft4
@kulakofft4 2 жыл бұрын
кажется тут не получится ни с useMemo, ни с useCallback, т.к. мы бьём ссылку на весь объект контекста, и перерендер происходит именно по этой причине. А ссылки на конкретные функции и так не меняются
@Alexander-fp4fs
@Alexander-fp4fs 2 жыл бұрын
а можешь плиз рассказать про reselect как он работает и в чем его польза?
@it-sin9k
@it-sin9k 2 жыл бұрын
Да, такое видео запланировано через пару выпусков :)
@renatvlasov4855
@renatvlasov4855 2 жыл бұрын
Не ожидал увидеть в видео мое не самое распространённое имя
@it-sin9k
@it-sin9k 2 жыл бұрын
Обычно в качестве имен и аватарок мы берем имена патреонов и спонсоров. Наверное и здесь так, видео инженер сам набирал имена, не уточнял откуда))
@set1k279
@set1k279 2 жыл бұрын
Я взял имена спонсоров ютуб
@xD-hu3gw
@xD-hu3gw 2 жыл бұрын
юзал контекст всегда) и решил пройти собес с температурой 38+ так на лажал ), и все равно мобыха лучше чем редах)
@Solozon3
@Solozon3 2 жыл бұрын
Было бы интересно увидеть точно такой же мини проект на recoil is, для сравнения
@it-sin9k
@it-sin9k 2 жыл бұрын
Идея хорошая :) нужно в будущем добраться до разных state management
@Moishe_Rubinstein
@Moishe_Rubinstein Жыл бұрын
В смысле в Редакс нет девтулс?
@it-sin9k
@it-sin9k Жыл бұрын
Там же вроде нет девтулс у контекста имелось ввиду
@kulakofft4
@kulakofft4 2 жыл бұрын
Когда решил использовать вместо redux котекст с редюсером, и потом удивляешься, что много бойлерплейта)))))) По сути то же самое написал. В чём проблема хранить данные непосредственно в провайдере? Почему вас так тянет усложнять кодовую базу редюсрами, экшнами и прочими? Не понимаю, простите
@it-sin9k
@it-sin9k 2 жыл бұрын
я не очень понимаю, как хранить данные в самом провайдере? типа вместо useReducer написать useState?
@kulakofft4
@kulakofft4 2 жыл бұрын
@@it-sin9k да, я не уточнил. Я объявляю через useState и в провайдер прокидываю значение и сеттер. Потом пользуюсь в компонентах как обычным стейтом. Все работает замечательно. Да, есть проблемы с излишними перерендерами, решаю их по мере необходимости и везде по разному.
@it-sin9k
@it-sin9k 2 жыл бұрын
В данном примере, я решил использовать useReducer вместо useState, т.к. периодически на проектах нужны сложные манипуляции с данными. И вроде как useReducer придуман, именно для того чтобы делать сложные вещи проще. Но я согласен, с тем, что в большинстве мест вероятно будет достаточно и useState
@starwalker.odessa
@starwalker.odessa 2 жыл бұрын
Получился анти-паттерн context hell? Потом все оборачивается в какой-то костыль, который может удалиться сборщиком мусора. Данная реализация немного заменяет Redux Thunk, но ...совершенно не решает вопросы, которые решает Redux Saga. Решение уровня "я у мамы программист" )
@TheProfessionalGambler
@TheProfessionalGambler 2 жыл бұрын
Каким образом сборщик мусора будет удалять костыль? И при чём Redux Thunk к этой реализации?
@bogdanshelomanov5668
@bogdanshelomanov5668 2 жыл бұрын
Еффектор бери , какой редакс
Лучшие примеры использования Context API
5:09
АйТи Синяк
Рет қаралды 14 М.
Learn React useReducer Hook with Examples
14:19
Lama Dev
Рет қаралды 171 М.
Now THIS is entertainment! 🤣
00:59
America's Got Talent
Рет қаралды 39 МЛН
React Batching от создания (v0.4.0) до React 18
36:20
АйТи Синяк
Рет қаралды 18 М.
React 17: Хук useContext
18:31
Школа web-программирования Constcode
Рет қаралды 11 М.
ПОЛНОЦЕННЫЙ ГАЙД ПО REACT CONTEXT
35:45
Ayub Begimkulov
Рет қаралды 9 М.
MOBX ПРОТИВ REDUX | РАЗБИРАЕМСЯ ЧТО ЛУЧШЕ
35:24
Learn React Hooks: useContext - Simply Explained!
15:46
Cosden Solutions
Рет қаралды 142 М.