Охаё! На связи канал Rimuru Dev. Искал видео по "Шина событий" для Unity. Но в итоге понял как ее реализовать на вашем примере, да же при том, что я впервые вижу язык JS (судя по расширению файла). Объясняете очень лаконично и доступно, благодарствую за труд.
К этому видео понравились комментарии, как автора, так и других разработчиков. Интересные размышления, которые помогают лучше оценить нужно ли или нет в каждом конкретном случае использовать данный паттерн. Спасибо!
Поздравляю вы изобрели сложный в дебаггинге велосипед с ивент басом, первый вариант правильнее, но надо в компонент записи не hasCall передавать(Вы правильно подметили компонент не должен знать про звонок) а к примеру isCancelled
@@it-sin9k да, но не только редакс имеет тулзу для дебагинга, а любой нормальный стм, паб саб создает неразберимый флоу и циклич зависимости особенно заметно в сложных приложениях. Я не говорю паб саб это антипатиерн, но он тут не уместен, особенно если у вас есть стм или котекст
Если утилиты внутри packages независимы (и, стало быть, не должны знать про конкретную бизнес-логику проекта, про Use Cases в терминологии DDD), почему в пакет с шиной складываются "бизнеслогические" события ‒ запись сообщения, звонок?
Да, есть такой обсуждение с коллегами тоже. Я относился к пакетам не совсем как к независимым утилитарным инструментам. А скорее как к инструменту заточеному под бизнеслогику. Который часто использует инверсию зависимостей. Так как многих вводит это в заблуждение, думаю надо начинать разделять эти понятия пакет и адаптер
Тут проблема в том, что компонент отвечающий за запись, зависит от данных о звонке, которые ему в принципе не нужны, вообще. Отсюда лишние рендеры тогда, когда они не нужны. Но вместо того, чтоб решить эту проблему, довольно простым способом, был изобретен костыль, который корень проблемы, в принципе, не решает, а лишь скрывает его в частном порядке. Достаточно было перенести логику переключения состояния на уровень выше.
Спасибо за комментарий. Не соглашусь лишь с несколькими моментами. "компонент отвечающий за запись, зависит от данных о звонке" (с) Нет не зависит от данных о звонке. Компонент зависит от события в шине, с названием "начало звонка". "был изобретен костыль, который корень проблемы, в принципе, не решает" (с) Смотря какую проблему вы для себя обозначили. Я в данном виде хотел уменьшить немного сцепление компонента звонков и компонента аудиозаписи. А так же уменьшить кол-во ненужных рендеров. Оставить только нужные. И с этим как раз справился "Достаточно было перенести логику переключения состояния на уровень выше." (с) Не всегда это так просто. Звонки могут присутствовать на любом экране. И на разных экранах могут быть голосовые сообщения или сообщения с музыкой. Со всем этим звонок может конфликтовать. Поэтому можно запилить верхнеуровневый менеджер потока аудио. Такое имплементировали, но это уже другой паттерн
@@it-sin9k с этим прекрасно справляется компонент на высшем уровне, который занимается всей логикой разных состояний и передает только нужные пропсы в дочерние. А дочерние будут рендериться только тогда, когда их пропсы изменяются. Вот что если появится еще какая-то логика, при которой надо остановить запись? Снова лезть в компонент и дописывать его? Компоненты они для того и компоненты, сделал и больше внутрь не лезешь, а используешь его, передавая пропсы. В данном случае у компонента только один пропс состояния записи, ему нафиг не нужно знать о каких-то посторонних состояниях. Если же такое возникает, как в примере из видео, то это толстый намек на проблемы в архитектуре. И чтоб решить простейшую проблему, путем избавление от внутреннего useState передачей состояния через пропсы, был изобретен костыль, который подложит жирную свинью в дальнейшей разработке.
@@profesor08 если просто выносить на компонент выше, появляется проблема props drilling, где нужно будет очень глубоко пробрасывать. В случае мессенджера и порядка 20 компонентов вниз возможно придется пробрасывать. А так же будет рендериться вся часть под дерева, начиная с того момента, где хранится state нужный
@@profesor08 Как только начинаешь добавлять контекст, появляются другие проблемы. Информации может быть много. Все держать в одном контексте или в разных? Значение и функцию обновляющую значения нужно пробрасывать через один и тот же контекст или разные? И куча других мелких проблем. Я использую контекст сугубо для других целей. Вот мой доклад на эту тему: ua-cam.com/video/fWm-m1-_dVA/v-deo.html
Хз, по мне так 2 доп.рендера не настолько критичны, а вот неявная передача событий по шине кому то нервишки попортит, скорее не тебе, а твоему коллеге.
Мысль очень даже здравая. Если вам нужна шина, лишь для 1 случая, то вероятно и пара рендеров лишних, точно не ухудшат сильно ваш перфоманс. Но если таких случаев гораздо больше, где хотелось бы использовать шину. То рано или поздно, кто-то добавит свое решение и команде придется научиться пользоваться этим инструментом. Это видео про то каким может быть этот инструмент :)
в моем опыте такие шины на средне-больших проектах всегда превращались в свалку событий, которые триггерят кучу обработчиков, которые опять триггерят события и так по запутанных цепочках. чтоб отследить логику простого функционала, приходится мучительно отслеживать такие цепочки, а кроме самого функционала приходится отслеживать все сайд эффекты. и все это держать в голове, каждый раз выстраивая все связи заново. и нельзя просто оборвать любую цепочку, ибо что-то перестает работать. уже после примерно 5 событий шина превращается в нечитабельного dsl монстра, требующего очень детальной документации
Я что то подобное видел, когда на одном проекте использовали mobX и злоупотребляли reaction на obervable переменные. Идея примерно такая же. Я же использую обычно шину для решения каких то узких задач. Например, вам нужно закрывать все попапы, если начался звонок. Т.е. для меня это мост для связи явно не связанного события одной сущности с UI компонентом другой сущности. И в таких случаях у меня даже наверное и не было не одного случая, когда несколько подряд событий вызываются друг за другом. Т.к. я минимально использую шину. Она словно дополняет стейт менеджмент, когда тебе нужно выполнить какую-то базовую операцию. Что то закрыть, что то переключить и т.д.
@@it-sin9k у меня на очень большом проекте сейчас люди сделали один дата сторидж, в который складывается весь стейт приложения, кусочками. нельзя сделать в апи ни одного запроса напрямую, надо всякий запрос положить в этот датастор. и идея его - в том, чтоб быть восстанавливаемым после перезагрузки состоянием. но неявно оно еще и у нас перерасло в такую вот бездонную перегруженую шину. 100+ человек на проекте, все вроде опытные, по 20 лет в айти (но в основном как бекендщики). и это уже мой далеко не первый проект, где так. во времена флеша там не было особо глубокой культуры разработки и фреймворков, народ на идею этой шины западал сразу. так что мне кажется, всегда при описании этого паттерна нужно приводить примеры, когда ее не надо использовать вообще - очень уж все падки вкорячить ее центральным обменником данных всего проекта
У нас на проекте, все построено поверх "шины данных" (это сложнее чем простая "шина событий"). Миллионы событий в секунду приходят на центральный сервис и перенаправляются подписчикам. Также реализованы RPC (при этом даже сессия запущенная в окне браузера также может зарегистрировать свой "удалённый метод"). Конечно, понять логику обработки сотни разных типов событий, задача не тривиальная, однако документация и/или TypeScript спасают. А для сложных цепочек событий у нас реализован RequestLogger, который хранит подробности выполнения бизнес-логики (какие события были, в каких модулях/классах, сколько обрабатывались по времени и тд).
А если пользователь нажмет на запись голосового собшения после звонка. Тогда получится фигня. Поэтому те два лишних рендера нужны были для того чтобы поставить и убрать дисейбл с кнопки записи аудио собшения.
А зачем в данном примере вообще нужен useEffect? Можно сразу во время рендера компонента вызывать setVoiceRecording и react синхронно перерендерит компонент. Тогда не бедет лишних ререндеров дочених компонентов и изменений в DOM
в моих глазах инверсия зависимостей идет плечо к плечу с инкапсуляцией. Разница лишь в том, какая из сторон диктует как будет выглядеть интерфейс абстракции. Если интерфейс диктуется принимающей стороной, в таком случае мы должны внутри абстракции создать еще адаптеры, к этому интерфейсу. А что это уже как не Dependency Inversion
А насколько большой может быть объект subscriptions? Стоит ли создавать один объект subscriptions для проекта и хранить внутри события для оповещения об изменениях компонентам?
@@it-sin9k мне кажется, что подобный подход не будет использоваться часто, это какие-то очень специфичные места, как например в видео, и скорее всего подписок много и не будет, так что хранение в 1 месте не будет вызыать никаких ишью, кмк
По факту, шина (это pub / sub паттерн) является одной из вариаций паттерна Observer. Только в паттерне observer ты можешь подписываться на все что угодно на любое поле в любом модуле. А в случае с шиной. У нас есть прослойка в виде eventBus пакета и вся коммуникация идет через этот пакет, но никто не подписывается на данные напрямую
Всем привет, ролик топ спасибо автору, но есть не большой вопрос а можете объяснить простым языком что такое шина, или может у вас есть видео про это? Гугл не помог.
Простым языком всегда сложнее всего объяснять))) Идея следующая. У вас есть несколько модулей (может быть как 2 так и 5, точное количество неизвестно). Сколько бы модулей не было, 1 модуль хочет например уведомить все остальное модули о каком то событии ( в нашем видео модуль по работе со звонками, хочет всем сообщить, что звонок начался). Суть шины, заключается в том, что уменьшает связанность между модулями. Модуль звонков уведомляет шину, что звонок начался. А кому надо, пусть подписывается на шину и ждет начало звонка (В нашем случае модуль записи голосового сообщения, слушает начало звонка).
Можно ещё напомнить, что есть возможность реализовать шину на том же редакс строе, у которого есть метод subscribe, который возвращает unsubscribe. Для этого совсем не обязательно пилить свой сервис :)
Так а зачем нужен redux в таком примере? Потом создавай экшен, думай как его задиспатчить (иногда диспатчить неудобно). А что если в redux еще другие данные, которые тоже тригерят колбек переданный в subscribe. Выглядит бесмысленно сложно
У нас довольно большой проэкт. Три года в разработке и вообще не используем redux. Как говорит Дэн Абрамов, redax нужен в очень малом колличестве проэктов.
Не лучше ли положить event bus в какой-нибудь контекст, чтобы удостовериться, что он один. А то в этом случае надеяться, что при импорте нам вернётся один и тот же закешированный объект не очень хорошо на мой взгляд
Не уловил идею, о каком именно закешированном объекте идет речь. Думаю, если есть переживания, что объект перезатирается кем-то, тогда лучше использовать Object.freeze По поводу контекста, я бы не использовал. Так как теперь ваша шина имеет зависимость ввиде реакта. При этом весь этот код будет прокручиваться реактом, не дай бог еще рендеры лишние вызовет, что крайне не желательно.
Имеете в виду проблему с перерендером при изменении результата селектора? Если речь об этом, то в видео вроде бы всё верно показано: изменения true -> false и false -> true приводят к перерендерам.
Пока найм мы приостановили, но вероятно опять откроем в районе нового года. Пока критерий найма бы следующий Senior Fullstack JS + гибридное посещение офиса в Минске :)
Не всегда разумно тянуть либу. Тянуть в проект 17.5кб, чтобы использовать RxJS как pub/sub механизм, выглядит как оверлоад. Потом либу надо еще обновлять поддерживать. Удердживать других разрабов использовать RxJS в других частях проекта. Проще кажется добавить 3-4 файла с кодом, добавить тесты к нему и забыть об этом коде на веки вечные
@@AndriiKuftachov если так, то и вопросов нет) Но если в вашем стеке нет (как у большинства React проектов). То добавлять RxJS для шины кажется избыточным
Не все так однозначно, к примеру, что бы использовать React.lazy компоненты которые будут рендериться должны экспортироваться через default export. Это конечно не аргумент, но смотрел как-то стрим Дэна Абрамова, он у себя в пэт проекте использовал default export и ему тоже сделали за это замечание, он ответил, что не видит в этом проблемы, так что, наверное, это дело вкуса и привычки
@@vitaliisliusar3089 ну если не злоупотреблять, то конечно проблемы не будет. Если, к примеру, в проекте ТС. А если нет ТС, и дефолтные эскпорты через алиасы, то это зло.
@@Vladyslav_Sliusar даже в епаме через год проходишь на миддла какие-то там экзамены. А в какой-нибудь небольшой компании где есть возможность брать большие блоки работы - ещё быстрее, если фигней не страдал а делал что-то
@@it-sin9k повторяю - даже в такой бюрократий как епам для джунов из рсскул через год аттестация на мидла. Я понимаю что вам заплатили но не надо игнорировать что я написал выше
Клёвое видео
Поздравляю с появлением спонсорской рекламы)
было бы неплохо увидеть и пощупать реализации на гитхабе, тебе звёздочки, нам возможность потыкать код, ну пожалуйста...
Охаё! На связи канал Rimuru Dev. Искал видео по "Шина событий" для Unity. Но в итоге понял как ее реализовать на вашем примере, да же при том, что я впервые вижу язык JS (судя по расширению файла). Объясняете очень лаконично и доступно, благодарствую за труд.
Спасибо! Да прибудет с Unity сила :)
К этому видео понравились комментарии, как автора, так и других разработчиков. Интересные размышления, которые помогают лучше оценить нужно ли или нет в каждом конкретном случае использовать данный паттерн.
Спасибо!
Поздравляю вы изобрели сложный в дебаггинге велосипед с ивент басом, первый вариант правильнее, но надо в компонент записи не hasCall передавать(Вы правильно подметили компонент не должен знать про звонок) а к примеру isCancelled
Почему он сложный в дебагинге? из-за того что через redux-devtools не виден?
@@it-sin9k да, но не только редакс имеет тулзу для дебагинга, а любой нормальный стм, паб саб создает неразберимый флоу и циклич зависимости особенно заметно в сложных приложениях. Я не говорю паб саб это антипатиерн, но он тут не уместен, особенно если у вас есть стм или котекст
@@it-sin9k Потому что события передаются неявно, по этому он сложен в дебагинге
Мы чаще всего на проекте пишем свои логгеры. С ними можно дебажить любой кодой очень просто. Точно надо сделать про это видео))
@@it-sin9k ты сталкивался с вложенными подписками в пабсабе?
Спасибо большое, было интересно) Чтобы вы посоветовали прочесть для изучения паттернов?
Patterns for humans чекан гитхаб репу
Чистую архитектуру недавно читал, мне понравилось. Но немного сложно из-за того что там примеры не на JS
Спасибо, но думаю эта книга для джуна как я будет сложновата, может ещё и опыта надо набраться
@@MAQULIYASO не надо тебе никакие паттерны тогда, вникай в базу и качай ее
Если утилиты внутри packages независимы (и, стало быть, не должны знать про конкретную бизнес-логику проекта, про Use Cases в терминологии DDD), почему в пакет с шиной складываются "бизнеслогические" события ‒ запись сообщения, звонок?
Да, есть такой обсуждение с коллегами тоже. Я относился к пакетам не совсем как к независимым утилитарным инструментам. А скорее как к инструменту заточеному под бизнеслогику. Который часто использует инверсию зависимостей. Так как многих вводит это в заблуждение, думаю надо начинать разделять эти понятия пакет и адаптер
Тут проблема в том, что компонент отвечающий за запись, зависит от данных о звонке, которые ему в принципе не нужны, вообще. Отсюда лишние рендеры тогда, когда они не нужны. Но вместо того, чтоб решить эту проблему, довольно простым способом, был изобретен костыль, который корень проблемы, в принципе, не решает, а лишь скрывает его в частном порядке. Достаточно было перенести логику переключения состояния на уровень выше.
Спасибо за комментарий. Не соглашусь лишь с несколькими моментами.
"компонент отвечающий за запись, зависит от данных о звонке" (с) Нет не зависит от данных о звонке. Компонент зависит от события в шине, с названием "начало звонка".
"был изобретен костыль, который корень проблемы, в принципе, не решает" (с) Смотря какую проблему вы для себя обозначили. Я в данном виде хотел уменьшить немного сцепление компонента звонков и компонента аудиозаписи. А так же уменьшить кол-во ненужных рендеров. Оставить только нужные. И с этим как раз справился
"Достаточно было перенести логику переключения состояния на уровень выше." (с) Не всегда это так просто. Звонки могут присутствовать на любом экране. И на разных экранах могут быть голосовые сообщения или сообщения с музыкой. Со всем этим звонок может конфликтовать. Поэтому можно запилить верхнеуровневый менеджер потока аудио. Такое имплементировали, но это уже другой паттерн
@@it-sin9k с этим прекрасно справляется компонент на высшем уровне, который занимается всей логикой разных состояний и передает только нужные пропсы в дочерние. А дочерние будут рендериться только тогда, когда их пропсы изменяются. Вот что если появится еще какая-то логика, при которой надо остановить запись? Снова лезть в компонент и дописывать его? Компоненты они для того и компоненты, сделал и больше внутрь не лезешь, а используешь его, передавая пропсы. В данном случае у компонента только один пропс состояния записи, ему нафиг не нужно знать о каких-то посторонних состояниях. Если же такое возникает, как в примере из видео, то это толстый намек на проблемы в архитектуре. И чтоб решить простейшую проблему, путем избавление от внутреннего useState передачей состояния через пропсы, был изобретен костыль, который подложит жирную свинью в дальнейшей разработке.
@@profesor08 если просто выносить на компонент выше, появляется проблема props drilling, где нужно будет очень глубоко пробрасывать. В случае мессенджера и порядка 20 компонентов вниз возможно придется пробрасывать. А так же будет рендериться вся часть под дерева, начиная с того момента, где хранится state нужный
@@it-sin9k для этого есть контекст
@@profesor08 Как только начинаешь добавлять контекст, появляются другие проблемы. Информации может быть много. Все держать в одном контексте или в разных? Значение и функцию обновляющую значения нужно пробрасывать через один и тот же контекст или разные? И куча других мелких проблем. Я использую контекст сугубо для других целей. Вот мой доклад на эту тему:
ua-cam.com/video/fWm-m1-_dVA/v-deo.html
Ты Мега крут, спасибо за такой четкий контент
Добро пожаловать на канал :)
Не совсем уловил, в какой момент у нас включается voiceCall. Я вижу только сброс стора на false. Без примера кода очень сложно въехать в пример.
а если событие называется toString ?)
не уловил вопрос?
у ibs на сайте отправка резюме не работает, чем они прокачают?
известная проблема - сапожник без сапог))
Хз, по мне так 2 доп.рендера не настолько критичны, а вот неявная передача событий по шине кому то нервишки попортит, скорее не тебе, а твоему коллеге.
Привет, можно подробнее?
Мысль очень даже здравая. Если вам нужна шина, лишь для 1 случая, то вероятно и пара рендеров лишних, точно не ухудшат сильно ваш перфоманс. Но если таких случаев гораздо больше, где хотелось бы использовать шину. То рано или поздно, кто-то добавит свое решение и команде придется научиться пользоваться этим инструментом. Это видео про то каким может быть этот инструмент :)
Автору огромное спасибо!
Но у меня возник вопрос: почему isVoiseRecording не хранить в сторе и не диспатчить ему состояние false при начале звонка?
Хороший контент. Спасибо.
Спасибо за видео
в моем опыте такие шины на средне-больших проектах всегда превращались в свалку событий, которые триггерят кучу обработчиков, которые опять триггерят события и так по запутанных цепочках. чтоб отследить логику простого функционала, приходится мучительно отслеживать такие цепочки, а кроме самого функционала приходится отслеживать все сайд эффекты. и все это держать в голове, каждый раз выстраивая все связи заново. и нельзя просто оборвать любую цепочку, ибо что-то перестает работать. уже после примерно 5 событий шина превращается в нечитабельного dsl монстра, требующего очень детальной документации
Я что то подобное видел, когда на одном проекте использовали mobX и злоупотребляли reaction на obervable переменные. Идея примерно такая же.
Я же использую обычно шину для решения каких то узких задач. Например, вам нужно закрывать все попапы, если начался звонок. Т.е. для меня это мост для связи явно не связанного события одной сущности с UI компонентом другой сущности. И в таких случаях у меня даже наверное и не было не одного случая, когда несколько подряд событий вызываются друг за другом. Т.к. я минимально использую шину. Она словно дополняет стейт менеджмент, когда тебе нужно выполнить какую-то базовую операцию. Что то закрыть, что то переключить и т.д.
@@it-sin9k у меня на очень большом проекте сейчас люди сделали один дата сторидж, в который складывается весь стейт приложения, кусочками. нельзя сделать в апи ни одного запроса напрямую, надо всякий запрос положить в этот датастор. и идея его - в том, чтоб быть восстанавливаемым после перезагрузки состоянием. но неявно оно еще и у нас перерасло в такую вот бездонную перегруженую шину. 100+ человек на проекте, все вроде опытные, по 20 лет в айти (но в основном как бекендщики). и это уже мой далеко не первый проект, где так. во времена флеша там не было особо глубокой культуры разработки и фреймворков, народ на идею этой шины западал сразу. так что мне кажется, всегда при описании этого паттерна нужно приводить примеры, когда ее не надо использовать вообще - очень уж все падки вкорячить ее центральным обменником данных всего проекта
@@romannakoval3624 Прикольный опыт. Я такого рода проекты не видел. Спасибо, что поделились своим опытом!)
У нас на проекте, все построено поверх "шины данных" (это сложнее чем простая "шина событий"). Миллионы событий в секунду приходят на центральный сервис и перенаправляются подписчикам. Также реализованы RPC (при этом даже сессия запущенная в окне браузера также может зарегистрировать свой "удалённый метод").
Конечно, понять логику обработки сотни разных типов событий, задача не тривиальная, однако документация и/или TypeScript спасают.
А для сложных цепочек событий у нас реализован RequestLogger, который хранит подробности выполнения бизнес-логики (какие события были, в каких модулях/классах, сколько обрабатывались по времени и тд).
@@EgorMoscowNeverSleep какой-то дикий оверенджиниринг
А если пользователь нажмет на запись голосового собшения после звонка. Тогда получится фигня. Поэтому те два лишних рендера нужны были для того чтобы поставить и убрать дисейбл с кнопки записи аудио собшения.
Для полноты примера не хватает визуального присутсвия кода в котором это событие броадкастится
А зачем в данном примере вообще нужен useEffect? Можно сразу во время рендера компонента вызывать setVoiceRecording и react синхронно перерендерит компонент. Тогда не бедет лишних ререндеров дочених компонентов и изменений в DOM
Как всегда топчег
низкий поклон!
7:00 в чём тут Dependency Inversion, если это классическое сокрытие?
в моих глазах инверсия зависимостей идет плечо к плечу с инкапсуляцией. Разница лишь в том, какая из сторон диктует как будет выглядеть интерфейс абстракции. Если интерфейс диктуется принимающей стороной, в таком случае мы должны внутри абстракции создать еще адаптеры, к этому интерфейсу. А что это уже как не Dependency Inversion
@@it-sin9k толсто
А насколько большой может быть объект subscriptions? Стоит ли создавать один объект subscriptions для проекта и хранить внутри события для оповещения об изменениях компонентам?
Учитывая что весь Redux тоже лежит в одном объекте, то пара подписок это вообще не страшно)
@@it-sin9k мне кажется, что подобный подход не будет использоваться часто, это какие-то очень специфичные места, как например в видео, и скорее всего подписок много и не будет, так что хранение в 1 месте не будет вызыать никаких ишью, кмк
И чем это отличается от паттерна Observer?
По факту, шина (это pub / sub паттерн) является одной из вариаций паттерна Observer. Только в паттерне observer ты можешь подписываться на все что угодно на любое поле в любом модуле. А в случае с шиной. У нас есть прослойка в виде eventBus пакета и вся коммуникация идет через этот пакет, но никто не подписывается на данные напрямую
Юзил паб саб ещё в жыквери. -- до того как это стало мейнстримом)
Видел уже rxjs в хуки кастомные пробуют. Xstate, кстати тоже ОЧЕНЬ интересная штука. Такие инструменты крутые графические !
Спасибо, было бы очень круто ссылочку на гитхаб с кодом, пресдставленным в видео.
Всем привет, ролик топ спасибо автору, но есть не большой вопрос а можете объяснить простым языком что такое шина, или может у вас есть видео про это? Гугл не помог.
Простым языком всегда сложнее всего объяснять))) Идея следующая. У вас есть несколько модулей (может быть как 2 так и 5, точное количество неизвестно). Сколько бы модулей не было, 1 модуль хочет например уведомить все остальное модули о каком то событии ( в нашем видео модуль по работе со звонками, хочет всем сообщить, что звонок начался). Суть шины, заключается в том, что уменьшает связанность между модулями. Модуль звонков уведомляет шину, что звонок начался. А кому надо, пусть подписывается на шину и ждет начало звонка (В нашем случае модуль записи голосового сообщения, слушает начало звонка).
@@it-sin9k Понял, спасибо
Спасибо за твои видео, на многое открыл глаза
Рад быть полезным!
Можно ещё напомнить, что есть возможность реализовать шину на том же редакс строе, у которого есть метод subscribe, который возвращает unsubscribe. Для этого совсем не обязательно пилить свой сервис :)
Не надо во все проекты тянуть Redux
@@sovaz1997 Звучит по сеньорски
Так а зачем нужен redux в таком примере? Потом создавай экшен, думай как его задиспатчить (иногда диспатчить неудобно). А что если в redux еще другие данные, которые тоже тригерят колбек переданный в subscribe. Выглядит бесмысленно сложно
У нас довольно большой проэкт. Три года в разработке и вообще не используем redux. Как говорит Дэн Абрамов, redax нужен в очень малом колличестве проэктов.
А можете сбросить статью или твит или еще где Дэн так говорит)
спасибо!
Не лучше ли положить event bus в какой-нибудь контекст, чтобы удостовериться, что он один. А то в этом случае надеяться, что при импорте нам вернётся один и тот же закешированный объект не очень хорошо на мой взгляд
Не уловил идею, о каком именно закешированном объекте идет речь. Думаю, если есть переживания, что объект перезатирается кем-то, тогда лучше использовать Object.freeze
По поводу контекста, я бы не использовал. Так как теперь ваша шина имеет зависимость ввиде реакта. При этом весь этот код будет прокручиваться реактом, не дай бог еще рендеры лишние вызовет, что крайне не желательно.
Спасибо за видос!
Ну да, сэкономили пару рендеров, а дальше импортишь react-spring, который тебе добавляет пару сотен рендеров сверху
с таким подходом, можно вообще ручки опустить и ничего не делать :)
На сколько мне известно, такая проблема с рендером относится к React до 17 версии. У Vue2 такого поведения не наблюдал.
Имеете в виду проблему с перерендером при изменении результата селектора? Если речь об этом, то в видео вроде бы всё верно показано: изменения true -> false и false -> true приводят к перерендерам.
Привет! Хотел бы узнать в вашу команду не нужен middle специалист, я думаю у тебя есть чему поучиться не только по видосам)
Пока найм мы приостановили, но вероятно опять откроем в районе нового года. Пока критерий найма бы следующий Senior Fullstack JS + гибридное посещение офиса в Минске :)
что за Язык?
JS + русский
Чтобы не создавать свой велосипед, можно взять RxJS для реализации шины. Замечательный инструмент!
XState Machine
Не всегда разумно тянуть либу. Тянуть в проект 17.5кб, чтобы использовать RxJS как pub/sub механизм, выглядит как оверлоад. Потом либу надо еще обновлять поддерживать. Удердживать других разрабов использовать RxJS в других частях проекта. Проще кажется добавить 3-4 файла с кодом, добавить тесты к нему и забыть об этом коде на веки вечные
@@it-sin9k можно изначально все делать поверх RxJS, тогда все ок.
@@AndriiKuftachov если так, то и вопросов нет) Но если в вашем стеке нет (как у большинства React проектов). То добавлять RxJS для шины кажется избыточным
@@it-sin9k У нас в проекте вообще Rx используют только для того, что бы события к кнопкам прикручивать 😅 И не запариваються 🤣
первый) не смотрел знаю что топ - чуть позже гляну
КрасавчЕГ))
Дефолтные эскпорты, чтобы навигация по проекту была максимально "удобной"
Не все так однозначно, к примеру, что бы использовать React.lazy компоненты которые будут рендериться должны экспортироваться через default export.
Это конечно не аргумент, но смотрел как-то стрим Дэна Абрамова, он у себя в пэт проекте использовал default export и ему тоже сделали за это замечание, он ответил, что не видит в этом проблемы, так что, наверное, это дело вкуса и привычки
@@vitaliisliusar3089 ну если не злоупотреблять, то конечно проблемы не будет. Если, к примеру, в проекте ТС. А если нет ТС, и дефолтные эскпорты через алиасы, то это зло.
неочевидная херня, но да, такое постоянно всплывает
ТЕХНОДРОМ - интересно, специалиста с 1 годом опыта взять на "обучение на реальный проект" и платить ему копейки, а не как мидлу. Прекрасная школа.
1 год опыта это мидл?
@@Vladyslav_Sliusar даже в епаме через год проходишь на миддла какие-то там экзамены. А в какой-нибудь небольшой компании где есть возможность брать большие блоки работы - ещё быстрее, если фигней не страдал а делал что-то
вопрос что вы называете копейками и конечно же вопрос почему джуну с 1 годом опыта, должны платить как мидлу о_О
@@it-sin9k повторяю - даже в такой бюрократий как епам для джунов из рсскул через год аттестация на мидла. Я понимаю что вам заплатили но не надо игнорировать что я написал выше
Есть способ намного проще - перейти на современный фреймворк, который не рендерит весь компонент от каждого чиха. Реакт диприкейтед
что за фреймворк такой?)
@@it-sin9k солид/свелт
@@dulyasdulyas4173 прикольно) надо бы изучить, как там все устроено)