Это скорее не недостаток Redux, а проблема современной фронтовой разработки - делать запросы, диспатчтить и работать с UI вперемешку и забывать про принципы SOLID и про направленность данных. Если банально использовать трех слойную архитектуру (UI, Business, DataAccess)то проблема решается. Пусть UI будет отражением нашего store. Business уровень - это просто фасад с методами которые UI будет вызывать, а методы, в свою очередь, будут делать fetch и диспатчить данные в store. Data Access - это обращение к эндпоинтам, кукам, и другим источникам данных. UI по сути работает только с интерфейсом Business. Таким образом еще и проблема тестирования решается. Пишем тест который дергает методы Business. Причем наш тест сможет проверить еще и работу реальных эндпоинтов. А можно в Business передавать DataAccess зависимость, и замокать данные. У нас получается полностью дырявый код который легко тестить. За видео 👍
В реальности прибегает заказчик с криками "Ой я забыл что нам нужно это и это и это завтра в релиз выпустить, не сделаете - уволю", и в таких случаях не до SOLID и грамотной архитектуры) Такое возможно только в серьёзных компаниях с одним проектом и грамотно настроенными бизнес-процессами. А таких компаний, увы, немного, очень немного.
@@michailb58 Это разные вещи. MVC это паттерн, где контролер создает модели и может обращаться к уровню доступа к данным. Затем на основании модели генерируются вьюшки. MVC - это способ создания представления и способ взаимодействия с пользователем. (модель - это автомобиль, собака, продукт ... Data Access - это не сами данные, а уровень, методы которого возвращают набор данных). Проблема которую поднял Илья - это безопасность получение и хранение данных и обработка данных. Поэтому я привел в пример Layerd Architecture. MVC приложение может использовать Layered архитектуру, а может не использовать. Так же и с редакс. Redux это просто библиотека, которую можно использовать как угодно. Редакс не обеспечивает безопасности данных, и не имеет особых ограничений. Если у вас на проекте редакс - это еше не означает что у вас есть какая либо архитектура.
А что с направленностью данных не так? Редакс располагает к таким зависимостям. У всех компонентов однонаправленный поток данных, тут суть что данные эти лежат в моносторе и то что раньше считалось достоинством (одни данные для ряда компонентов) для асинхронного получения данных стало недостатком т.к. нет понимания какой из компонентов должен запрашивать эти данные кто обновлять и т.д. многие просто завязывают компоненты на результат работы другого компонента и не парятся, данные же есть)
@@Glotka UI'ю, по хорошему, должно быть все равно на бизнес логику. UI забирает данные с селектора и отрисовывает из. А асинхронные запросы, работа со стором и другие скучные вещи - это забота бизнес логики. Вот к примеру, у нас есть onClick который к примеру делает await fetchProducts а потом берет shoppingCart из props которую получил из connect или константу из useSelector. Пока выполнялся асинхонный запрос наши данные уже могли измениться в сторе, а проперти в замыкании до сих пор ссылаются на старые данные. Далее мы могли на основании некорректных данных показать ошибку, или вызвать диспатч. Это может быть примером того, что случается когда пробраммист не следит за направлением потока данных. Программист забыл что пропсы в замыкании у коллбэка. Так же UI обратился к серверу напрямую. UI не должен ничего знать об эндпоинтах - это забота бизнеса. Проблемы бы не было, если бы код поместили в асинхронную бизнес функцию и извелкали данные из стора после того как получили ответ с сервера.
@@ddflrucслабо представляю как могут авто тесты помочь, они же смотрят как на черный ящик. Да и юнит тесты тоже не должны спасти. В любом случае если продукт требует сторонних средств - это минус. Так то конечно всякими анализаторами это можно искать
1. стабильный state, который в каждый момент валидный и консистентный - преимущество redux, и вообще систем с глобальным state менеджером. В том смысле, что у вас всегда ваши данные и переменные состояние находятся в одном из учтённых вами состояний - finite state machine либо конечный цифровой автомат. + а учитывая наличие инструмента redux-dev-tools вы можете просматривать все шаги, которые были выполнены. И не только на своей dev машине. 2. асинхронные запросы вы можете реализовывать как вашей душе угодно - их не обязательно засовывать в redux. К тому-же запустил загрузку данных (либо асинхронную операция) - поменял state, получил результат либо ошибку - поменял state. В чём проблема-то? 3. запрос данных с разных уровней компонентов - разве это проблема? По отношению к вашему примеру, разве сложно описать единый hook, который будет проверять наличие данных и запускать загрузку если их нет. А после использовать этот hook на всех уровнях - это разве не решение по разрыву описанной вами зависимости? Другими словами делаем что-то на подобии: function getUsersHook(){ const dispatch = useDispatsh(); const {status, data} = useSelector(usersSelector); useEffect(() => status=="notStarted" && dispatch(loadUsersAction), [status]); return [status!="hasData", data]; } И используем её в обоих компонентах в виде const [isUsersLoading, users] = getUsersHook(). Да, в loadUsersAction() надо проверить status может другой компонент уже запустил загрузку, и обновить его при старте загрузки и при завершении. Заодно явная связь 2-х компонент по тому что они обе используют один getUsersHook().
Я если понимаю, что есть данные которые используются не в одной компоненте на странице, а в нескольких, просто выношу запрос на получение этих данных на более высокий уровень. В том же next.js запрашиваю их на уровне page. Да и даже если один компонент использует, выношу на более высокий уровень часто, потому, что для компоненты по большому счету пофиг откуда к ней прилетают нужные ей данные, а выпиливание асинхронщины из компоненты упрощает ее понимание.
Ну получается, что все компоненты, потребляющие стор, неявно зависят от этого компонента уровнем выше. При нормальной архитектуре об этом вообще не нужно задумываться. react/rtk-query и apollo решают это проблему из коробки и правильным способом.
Все вскрылось, когда начали использовать Apollo Client, с тех пор если и использую redux - то условно только для данных, которые создаются кодом приложения "подлежат сериализации" в какой-то persistent storage (локальный, как localstorage или удаленный, как redis, aerospike, и т д )
К примеру к таким кейсам - ловил плавающий баг, запрос был в компоненте сайдбара слева. На десктопе запрос есть всё хорошо данные приходят используются в основной части приложения. На планшете сайдбар не отрисовался - запроса нет - данных нет. Сиди думай и ищи источник проблемы.
Илья, какие можешь назвать минусы эффектора (в начале ролика ты упомянул что уже все) или что из самых больших минусов по твоему мнению? Связанность сторов, способ описания логики, то же разделение кеша, тестируемость, дебагабилити?
Знающие люди, подскажите, я может не знаю, но разве в условном Vuex такой же проблемы нет? Если мы затянули в стейт данные из одного компонента(или даже роутером, допустим), то нам по факту ничего не мешает сделать обращение к этим данным(забрать их из стейта) из другого компонента, который их не тянул.
Как раз недавно у меня на проекте появился такой компонент, который использует те же данные который подгружал другой, но я решил эту проблему вызовом экшена и в этом компоненте, так как данные могут быть не актуальны и их нужно обновить в любом случае.
Спасибо, Илья, как-то не задумывался ранее на эту тему, обычно в своих проектах оборачивал всё в один слой DataLayer и там грузил все кеш-данные, который нужны многим и так как этот самый DataLayer - это самамя верхняя компонента и в неё всё завёрнуто, то так просто её не удалить,
Если потребителями данных являются несколько дочерних компонентов компонента "А", значит запрашивать их должен компонент "А". Это не недостаток Redux, это недостаток архитектуры конкретного приложения.
Только у библиотек из данного списка будет друга проблема, это контролирование жизни кеша, в rtk-query в 0.2 версии можно только время установить, по истечению которого кеш очистится, в 0.3 можно передать callback, по которому вы сделаете очистку кеша, или в принципе кеш очистить весь, что тоже не очень удобно делать. Проблема описанная решается так, или компоненты-дети используют данные, которые запрашивает их компонент-родитель, или, если вы не хотите перезапросы частые делать, то просто проверяете наличие данных в сторе.
Должен быть компонент, ответственный как за загрузку данных, так и за их очистку. В useEffect не зря придумали функцию очистки при return. Если это, скажем, список юзеров и где-то рядом - статистика о загруженых юзерах, то очевидно - это компонент, содержащий их обоих. Дергать "бесконечно быстрый интернет" это такое себе. Можно спокойно выстроить более сложную иерархию и передавать просто id в пропсы дочерних компонентов и те будут селектором выбирать данные, никаких с этим проблем не будет, они изначально зависимые, вложенные компоненты. Тоже самое с различными визардами. Выбирать и очищать данные будет компонент, содержащий все степы. Не нужно в степы "пихать" логику загрузки данных. Селекторы - пожалуйста. Но бывают и особые случаи. Если мы делаем e-commerce, то список товаров по фильтрам может загружать, очищать верхний компонент, а класть товары в корзину уже будет карточка товаров самостоятельно. В нее в пропсы придут данные, чтоб она отрисовалась, но она будет диспатчить данные самостоятельно. Даже, если нужно перевыбрать товары, по какой-то причине при добавлении в корзину (например забрали последний), и это происхойдет в thunk-е или саге, которую вызовет карточка товара, и это затем подхватит верхний компонент для отрисовки всех карточек - тоже не проблема. Легко отслеживается flow, главное использовать TypeScript. С бОльшего проблема надуманная. Надо реально быть косячным, чтоб такие зависимости сделать, как в видео.
По поему это очевидная проблема, любой компонент, который получает данные должен их сначала запросить. Это явно не проблема redux, а косяк разработчика, который на кнопки жмёт и мозги не включает. Но как правильно подметил автор, если три компонента будут одновременно смонтированы на страницу мы упремся в проблему дедупликации 3х одинаковых запросов. React query в этом плане это чудо какое-то, сам был ярым поклонником redux, перечитал доку до дыр, пересмотрел наверное все возможные уроки и подходы, но как увидел RQ влюбился с первого взгляда, пересел и не жалею. Кода на процентов 30 меньше, функционала из коробки больше, кастомизировать можно до бесконечности, под задачи любых сложностей, а главное забыл об одностороннем потоке выполнения flux, как о страшном сне.
Мне кажется, это проблема не Редакс, что 1 компонента, берет данные из Редакс, и другая эти данные заполняет, но они назависимы друг от друга в коде. Я мб что-то упускаб, но почему бы в таком случае, не проверить стейт, есть ли там данные, и если нет, то запросить? Можно мне кажется в принципе организовать код так, что это будет делаться всегда, для каждого запроса. Но мб есть какие-то подводные камни. Уже давно с экосистемой Редакс не работал.
Я когда работал с NGRX никогда не дергал экшен загрузки с компонента потребителя и вообще старался сделать так чтоб этот экшен вызывался максимум один раз.
Если запрос данных не в компоненте держать, а в отдельном контроллере, который загружает все необходимые для страницы данные, то никаких фантомных связей не будет. Возможно я привык с такой архитектурой с отдельной загрузкой данных работать конечно, но мне кажется что проблема немного преувеличена. Но я бы с радостью послушал про инструменты, которые её решают, но при этом так же хороши в стейт-менеджменте, как redux.
а если просто управлять стором не в компоненте D, а в компоненте А. То есть загрузка происходит в компонента А, тогда как уже в дочерних компонентах будет проиходить просто получение данных из стора. В своих проектах на Nuxt я всегда стараюсь придерживаться такой политики. данные у меня запрашиваются в pages в хуках, а непосредственно уже работа с этими данными в дочерних компонентах
Интересно послушать сравнение Redux и MobX. Один реализует иммутабельный подход, второй мутабельный. В свое время был озадачен вопросом на собеседовании: "В каких приложениях лучше использовать мутабельный (mobx) и иммутабельный (redux) подход?". Так и не смог найти для себя вразумительный ответ, так как считаю, что любое приложение можно написать на любом из них.
По моему мнению, это ошибка разработчика и нарушать правило low coupling можно через любой инструмент. Если мы с одного места получаем данные и отдаем 3 компоненту, в таком случае как мы сможем убрать зависимость с помощью какого-либо инструмента, если мы в будущем планируем убить этот компонент/фетчинг и перестать фетчить данные? А как кэш спасет, если мы убрали фетчинг и у нас больше нет данных? Хорошо, мы получаем данные например через react-query, добавляем в кэш и в 3 компоненте дергаем кэш. Это спасает нас? Думаю нет. Ждем решения этой проблемы :)
Оооо, а я момент с кешем решил демократичными хранилищами. На вроде одно хранилище, один запрос за данными и куча экземпляров которые могут командовать, но команды демократичные, если загрузка, то одна, если ожидание ответа то ответ всем, когда загрузка закончится, если отменить загрузку, то только когда экземпляр один, все остальные будут ждать загрузку
Все используют redux как кэш, потому что даже уже на этой стадии становится понятно какой адский пайплайн-боилерплейт по всей кодовой базе приходится городить ради каждой дополнительной сущности и действия. Состояние внутри react-компонент в 99% случаев абсолютно всех устраивает, и никакой проблемы не появляется. Проблемы начинаются не из-за отсутствия использования redux-а, а когда его таки используют.
Илья в светлом и мирном будущем(надеюсь) хотелось бы увидеть (и услышать) твоё мнение на альтернативные Редаксу лабы по управлению состоянием и их сравнение друг с другом
Так себе проблема. Мне вот в Redux больше всего не нравится то, что данные хранятся как дерево, а не как граф. Подобно MobX, например. Поэтому постоянно приходится совершать работу по их преобразованию, это порождает многословность. Было бы здорово поверх редакса написать иммутабельную базу данных, где можно определить схемы, чтобы она автоматически обрабатывала связность объектов, позволяя с ними работать как с графом. Думаю, значительную долю многословности это бы убрало совмещая подходы Redux и MobX.
Загружаем данные один раз на самом верху - потребляем всеми ниже расположенными компонентами. Если у вас компонент, находящийся ниже по дереву, загружает данные, потребные компоненту стоящему Выше - то Вы пососали на уровне проектирования. При любом случае ожидания данных выше чем есть на данный момент, диспатч экшона с фетчингом по дефолту должен быть вынесен выше.
Ну например есть список, для каждого элемента списка можно сделать какую-то операцию, потом список целиком надо обновить - по сути нижестоящий компонент обновляет вышестоящий и это в данном случае логично
Все пытаюсь сматчить Redux и подход, что глобальные объекты это плохо. Не вяжется у меня никак. Может кто знает и может объяснить почему Redux это хорошее решение, хотя это глобальный объект для приложения и появляются связи всего со всем?
Проблема существует. Но решается композиций компонентов. Такое часто возникает когда открываешь сайт, а он должен "прогрузить" всякие справочные данные(профиль, страны, локали и всякие там списки). И нужно это отслеживать при загрузки приложения и в правильном порядке вызывать экшена просто. Такие вещи дополнительными библиотеками мы никогда не решали. Мне кажется что в некоторых случаях бессмысленно надстройки еще включать если архитектура приложения уже хаос.
Если я все правильно понял, то это видео про то что кэш нам поможет решить проблему с двойной загрузкой данных, если комопненты и B и D будут сами загружать данные. Слишком хайпово назвали "Фатальный недостаток Redux ;)" смайлик конечно к месту =). Подписался на канал жду еще видео, спасибо за работу и интересный подход с рисованием на планшете
Ну не знаю, мне кажется самая идея вот этого стора - есть в том что компоненту "B" стрго пофиг откуда в сторе данные. Как говорится, на то он и единый стор.... А то если как - то показывать эти засисимости компоненов друг от друга то сложность этих связей быстро растет. Да, есть определенные вопросы, но это же как раз и есть "побочный" эффект от упрощения утравления данными...
Не очень понятно, что в данной ситуации смущает и в чем недостаток. Неявной связи B - D таки нет. Есть явная связь B - store. Кто, откуда, когда и как обновит store нам плевать. Если мы удалим D у нас абсолютно ничего не поменяется и не сломается. В store будет init.state, в котором, очевидно, будут данные для B. Другой вопрос, что по-хорошему, зависимость от store надо бы делегировать, скажем компоненту A, который будет выступать медиатором. Ждём следующие выпуски с раскрытием темы
Идеальная ситуация когда данные поступают из одного источника А и передаются компонентам ниже. Но когда компоненты ниже А начинают менять данные для него, это и есть повод для бесконечных рассуждений 😁
"Кто, откуда, когда и как обновит store нам плевать" - чего то совсем уж упрощено. Компоненты которые получают данные на входе действительно все равно откуда эти данные пришли. Но когда мы берем данные с состояния нам придется заморочиться как они туда попали, и есть ли они там вообще. Модель была бы красивой если бы реально все данные были в нашем store. Но в веб как правило как раз ничего нет, частичные снимки предоставляет бекенд по запросам. Как на меня, сложность организации загрузки этих данных по требованиям компонентов превосходит по сложности сам redux (особенно "радует" что часто разные запросы к бекенду дают одни и те же объекты в разной степени детализации, то все держать в store в синхронизированном виде весело)
@@ОлегМакарчук-о9р "как они туда попали" странно, что у вас могут возникнуть такие вопросы. Так или иначе через делегата, который таки должен заниматься инвалидацией и соблюдением контракта. В таком случае, не очень понятно, зачем вам знать, кто выпустил валидный контракт.
Круто! У меня в проекте экшоны вьюкса чаще всего дергаются хуками роутера. А если какие-то компоненты хотят дергать экшоны из себя, то это либо корневые, либо ui компоненты. Избегайте говнокода Придумайте себе правила и строго их придерживайтесь :)
Я просто оставлю это здесь 😀 th-cam.com/video/XEt09iK8IXs/w-d-xo.html PS. Когда-то столкнувшись с проблемой описаной в ролике закончил написанием своего криввенького кеш менеджера).
Первое что пришло в голову во время обсуждения - завести/написать инструмент, который будет при обращении к данным либо грузить их с сервера, либо с кеша) компоненту по сути лучше вобще не знать как к нему попадут данные))
Очень интересно про GraphQL API / Apollo & Redux. Безумная путаница в просторах интернета, в одних источниках кричат, что удаляем Redux - устанавливаем GraphQL, в других говорят что Redux и GraphQL про разное и их можно использовать совместно. Во первых новичку и так не просто вклиниваться в поток, так еще и про технологи в каждой статье и на каждом канале говорят так уверенно, что начинаешь теряться в силу своей неопытности.
Apollo и Redux про разное, но все же это пересекающиеся множества. Особенно когда redux используется по большему счету как кэш + состояние "грузится/загрузилось/ошибка". В таких случаях gql в лице apollo может безболезненно заменить redux.
Есть ещё одна большая проблема в Redux, допустим есть некая лента из 400 элементов, и эти элементы хранятся в сторе, при попытке изменить один элемент, допустим поставить лайк, придётся перезаписывать весь обьект, как по мне это одна из самых больших проблем.Redux не подходит для работы с большими обьёмами данных, по этому я препочитаю MobX. ибо он более лаконичен и позволяет не перезаписывать все данные при попытке изменения одного поля, да и реактивность достаточно приятная штука. P.s. Открыт к дискусии)
попробуйте rtk и в особенности immerjs, который там в комплекте с редьюсерах идет - больше никакого головняка при работе с глубокими вложенностями или изменением каких-то массивов.
Чтобы избежать этой проблемы необходимо создавать компоненты- контейнеры, которые должны диспатчить все экшены и подключаться к стору. В данном примере это компонент А. Вся логика работы со стором должна хранится там С появлением хуков стало заманчиво использовать диспатч на нижних уровнях вложенности. Илья привел отличный пример, что из этого может выйти
Хорошо бы было если б автор сказал , а вот используя такие стэйт менеджеры …. У нас нет такой проблемы. Хотя для меня лично все перечисленное выше не проблема.
отличное кликбейтное название вынес для себя, что фатальный недостаток redux - это, внезапно, разработчики, которые вносят неявные зависимости в код. но, к сожалению, от таких проблем спасет разве что wix/тильда а так да, если пальцы в розетку засунуть - будет бобо. другое дело, являются ли любители совать пальцы в розетки ФАТАЛЬНЫМ НЕДОСТАТКОМ розеток?
Много однотипных комментариев, но этот с метафорой про розетку, отвечу. Точно так же как дизайн розетки эффективно МЕШАЕТ совать пальцы, точно так же хорошее архитектурное решение своей архитектурой мешает делать плохо. У питона это называют to fall into the pit of success. Поэтому да, если бы розеткой можно было бы легко ударить себя током и если бы много кто это делал - это было бы фатальным недостатком розетки
@@JavaScriptNinja из документации: >Redux is a tiny library по-идее, чтобы tiny library превратилась в архитектурное решение, которое будет в состоянии помешать кому-то делать плохо, ей стоит обрасти принципами и подходами, как минимум идея же о том, что на столько сильное зацепление компонентов - это плохо, как по мне, довольно проста и вполне претендует на роль одного из таких принципов. и если мы допускаем такие ошибки при проектировании, довольно легкомысленно будет ждать спасения от react query, akita, recoil, apollo, relay, mobx, чего-угодно. вот wix - да, с ним шансы есть надеюсь мой комментарий был выбран не для того, чтобы сместить обсуждение на метафору
@@JavaScriptNinja очень интересное утверждение, зачем же тогда они нужны? понимание, как делать не (не)надо и есть тем самым базисом, который не даст нам отстрелить себе колени с последующими обвинениями ужасной технологии, которая нам все сломала. у нас же все-таки не просто так есть прокладка между клавиатурой и либами/фреймворками. а то бы нас уже no-code давно заменил
@@oleksandrh3994 все очень просто - в контексте бизнес-проекта (когда мы пишем прикладной код а не системный) программист должен быть сосредоточен на решении бизнес задач. Чем меньше ему необходимо знать вещей, которые невыразимы в коде и неконтролируемы автоматически - тем эффективнее будет работа. Конвенции и архитектурные решения не имеющие воплощения в коде приводят к задержкам на код-ревью, многократно подтверждено гитлабом
какая то выдуманная, притянутая проблема, обоснованная частным абстрактным случаем, ни о чем. то как ты строишь поток данных между компонентами через стор, это только дело твоих рук и в этом нет вины редакса, короче тема уровня инфоцыганства
Я с такой проблемой не раз сталкивался. Особенно в больших проектах, данные ошибки съедает много времени (там таких не явных связей может быть несколько). Здесь говорилось больше про то, что подход Redux и его аналогов, не защищает от таких рода ошибок, и этим часто грешат разработчики до конца не разобравшиехся в инструментарии.
"фатальный недостаток" это термин, который означает неприятие чужого кода (разработки) в силу каких то причин. В этом ролике не про то ... и как по мне, все очень заумно, возможно и правильно судя по комментариям, но я ниче не понял)))
Все что я услышал, это не недостаток редакса, а не правильная архитектура приложения:) все легко решается. чем мне нравится редакс, что он не делает магии, есть простые чистые функции, которые легко покрываются тестами.
Я могу быть неправ но вроде как скрытой зависимости можно избежать используя либу reselect. + мне кажется когда компонент В использует тот же стейт что и D, но они не связаны и в разных местах приложения. Не логично ли сделать либо 1) Вызвать loadUsers где то выше, у родителя. 2) Вызвать loadUsers у обоих при монтировании компонента. UPD: досмотрел до конца. хммм ну возможно стоит чекнуть эти либы, но если честно есть ощущение что логика будет более туманна в таком случае. Как ты и сказал, магически будут работать.
Про CombineReducers и разделение стейта на куски видимо вы не в курсе. Также как про то, что инициацию получения данных лучше делать в зависимости от событий раутинга. Объяснять рукожопость программера минусами библиотеки - такой себе ризонинг.
как ниже заметили - это не недостаток стейт менеджера, а косяк тех, кто дизайнил приложение. Так же, как и распространенная ошибка складывать в стейт локальное состояние, ошибка дева, а не вина стора. Редакс меня миновал на реакте, а вот ngrx и vuex на ангулар и вуй зацепили. Из того, что не понравилось помимо упомянутых ошибок самих разработчиков - то, что сторы заставляют писать прямо таки дофигище текста ради простой вещи.
Спасибо за упоминание локального состояния. К примеру есть модальное окно у которого есть состояние show/hide где правильно хранить и изменять данное состояние? И почему?
@@ev_geniy17 в обычно ситуации вы, наверное, хотите видеть show/hide в качестве пропсов/инпутов для своей модалки т.е прокидываете значения из родителя.
@@dmytroputrin980 получается что состояние хранится в компоненте модалки, но зависит от пропсов и где-то в сторе компонента родителя будет действие и состояние которое будет менять пропсы для модалки
@@ev_geniy17 да, в идеале `showModal` как раз и будет браться из локального состояния родителя. Есть куча вариантов сделать доступность вызова глобальным аля через сервис или даже сторе, но с этими подходами лично у меня всегда было больше проблем, чем выгоды.
D запрашивает данные, B их отображает. Какой смысл сохранения компонента B, если данные не будут запрашиваться в D, а сам компонент B является тупым, просто отображая поступившие данные В нормальных проектах эти компоненты явно связаны по средствам вызова компонента B в компоненте D с передачей пропса с данными
Проблема очень просто решается. Нужно помимо переменной users: User[] иметь переменную isUsersLoaded: boolean. Компонент B и D проверяют isUsersLoaded: если false, грузят данные; если true, берут из стора. В идеале, конечно, эту логику должна в фоне делать библиотека для загрузки данных, чтобы вручную не пилить в два раза больше переменных. Не в курсе, есть ли такой функционал в react-query, swr и т.п.
На 10.50 полнейший бред с недостатком, не выдержал смотреть эт до конца. Все зависит от того, каким образом вы строите архитектуру. Если кривые руки, то естественно будуте ныть, что мол недостатки
Во фронтенде большинство технологий плюс-минус одинаковые. К чему постоянно вот этот пафос - непонятно. Чуваки, идите куда-нибудь в геймдев, становитесь экспертами там(но вы не пойдете, потому что сложна и порог входа выше в десяток раз).
У фронтов слегка надуманные проблемы))) Можно же кешить на стороне сервера, если не хочется трафик гонять, то почему не сделать Класс для работы с апи, который и будет Кешить что нужно, а что нет. Фронтеры почему-то не хотят кодить: то только думают как использовать что-то готовое, которое вообще не подходит под решение задачи? =))
Есть еще одна проблема редакса, связанная с описанной в видео. Она заключается в том, что мы не знаем, КОГДА данные для потребления будут доставлены. Допустим, компонент B знает, что D загрузит данные, но он не знает, когда это случится. И если просто завяжется на эти данные, то мы можем иметь неприятные эффекты, как 1) мерцание UI (сначала отрендерилось одно, потом другое 2) повторный рендеринг (что плохо влияет на производительность 3) иногда ошибки в вычислениях внутри компонента. Как уже заметили выше, частично эта проблема решается организацией архитектуры. То есть ты видишь, что компонент D грузит данные и понимаешь, что удалять его нельзя :)) но все равно могут происходить неприятные моменты из-за того, что другие компоненты, например, могут дергать экшены стора через D
Как мне кажется Redux создавался ещё в те времена, когда активно использовался jquery, как рендер html 🤣. Хватило бы и react, но мы же не стоим на месте.
хорошую тему поднял, не задумывался даже о такой проблеме. Будет интересно посмотреть продолжение.
Это скорее не недостаток Redux, а проблема современной фронтовой разработки - делать запросы, диспатчтить и работать с UI вперемешку и забывать про принципы SOLID и про направленность данных. Если банально использовать трех слойную архитектуру (UI, Business, DataAccess)то проблема решается. Пусть UI будет отражением нашего store. Business уровень - это просто фасад с методами которые UI будет вызывать, а методы, в свою очередь, будут делать fetch и диспатчить данные в store. Data Access - это обращение к эндпоинтам, кукам, и другим источникам данных. UI по сути работает только с интерфейсом Business. Таким образом еще и проблема тестирования решается. Пишем тест который дергает методы Business. Причем наш тест сможет проверить еще и работу реальных эндпоинтов. А можно в Business передавать DataAccess зависимость, и замокать данные. У нас получается полностью дырявый код который легко тестить.
За видео 👍
В реальности прибегает заказчик с криками "Ой я забыл что нам нужно это и это и это завтра в релиз выпустить, не сделаете - уволю", и в таких случаях не до SOLID и грамотной архитектуры) Такое возможно только в серьёзных компаниях с одним проектом и грамотно настроенными бизнес-процессами. А таких компаний, увы, немного, очень немного.
UI - View, Business - Controller, DataAccess - Model 😎
@@michailb58 Это разные вещи. MVC это паттерн, где контролер создает модели и может обращаться к уровню доступа к данным. Затем на основании модели генерируются вьюшки. MVC - это способ создания представления и способ взаимодействия с пользователем. (модель - это автомобиль, собака, продукт ... Data Access - это не сами данные, а уровень, методы которого возвращают набор данных). Проблема которую поднял Илья - это безопасность получение и хранение данных и обработка данных. Поэтому я привел в пример Layerd Architecture. MVC приложение может использовать Layered архитектуру, а может не использовать. Так же и с редакс. Redux это просто библиотека, которую можно использовать как угодно. Редакс не обеспечивает безопасности данных, и не имеет особых ограничений. Если у вас на проекте редакс - это еше не означает что у вас есть какая либо архитектура.
А что с направленностью данных не так? Редакс располагает к таким зависимостям. У всех компонентов однонаправленный поток данных, тут суть что данные эти лежат в моносторе и то что раньше считалось достоинством (одни данные для ряда компонентов) для асинхронного получения данных стало недостатком т.к. нет понимания какой из компонентов должен запрашивать эти данные кто обновлять и т.д. многие просто завязывают компоненты на результат работы другого компонента и не парятся, данные же есть)
@@Glotka UI'ю, по хорошему, должно быть все равно на бизнес логику. UI забирает данные с селектора и отрисовывает из. А асинхронные запросы, работа со стором и другие скучные вещи - это забота бизнес логики. Вот к примеру, у нас есть onClick который к примеру делает await fetchProducts а потом берет shoppingCart из props которую получил из connect или константу из useSelector. Пока выполнялся асинхонный запрос наши данные уже могли измениться в сторе, а проперти в замыкании до сих пор ссылаются на старые данные. Далее мы могли на основании некорректных данных показать ошибку, или вызвать диспатч. Это может быть примером того, что случается когда пробраммист не следит за направлением потока данных. Программист забыл что пропсы в замыкании у коллбэка. Так же UI обратился к серверу напрямую. UI не должен ничего знать об эндпоинтах - это забота бизнеса. Проблемы бы не было, если бы код поместили в асинхронную бизнес функцию и извелкали данные из стора после того как получили ответ с сервера.
Как многие подметили, это явно не проблема redux, это проблема архитектуры и абстракция
Например если редюсер больше не используется - по коду это трудно понять, и это проблема как рез редукса
@@sergsuper Это проблема отсутствия авто-тестов на проекте, как по мне.
@@ddflrucслабо представляю как могут авто тесты помочь, они же смотрят как на черный ящик. Да и юнит тесты тоже не должны спасти. В любом случае если продукт требует сторонних средств - это минус. Так то конечно всякими анализаторами это можно искать
1. стабильный state, который в каждый момент валидный и консистентный - преимущество redux, и вообще систем с глобальным state менеджером. В том смысле, что у вас всегда ваши данные и переменные состояние находятся в одном из учтённых вами состояний - finite state machine либо конечный цифровой автомат.
+ а учитывая наличие инструмента redux-dev-tools вы можете просматривать все шаги, которые были выполнены. И не только на своей dev машине.
2. асинхронные запросы вы можете реализовывать как вашей душе угодно - их не обязательно засовывать в redux. К тому-же запустил загрузку данных (либо асинхронную операция) - поменял state, получил результат либо ошибку - поменял state. В чём проблема-то?
3. запрос данных с разных уровней компонентов - разве это проблема?
По отношению к вашему примеру, разве сложно описать единый hook, который будет проверять наличие данных и запускать загрузку если их нет. А после использовать этот hook на всех уровнях - это разве не решение по разрыву описанной вами зависимости?
Другими словами делаем что-то на подобии:
function getUsersHook(){
const dispatch = useDispatsh();
const {status, data} = useSelector(usersSelector);
useEffect(() => status=="notStarted" && dispatch(loadUsersAction), [status]);
return [status!="hasData", data];
}
И используем её в обоих компонентах в виде const [isUsersLoading, users] = getUsersHook(). Да, в loadUsersAction() надо проверить status может другой компонент уже запустил загрузку, и обновить его при старте загрузки и при завершении. Заодно явная связь 2-х компонент по тому что они обе используют один getUsersHook().
Я если понимаю, что есть данные которые используются не в одной компоненте на странице, а в нескольких, просто выношу запрос на получение этих данных на более высокий уровень. В том же next.js запрашиваю их на уровне page. Да и даже если один компонент использует, выношу на более высокий уровень часто, потому, что для компоненты по большому счету пофиг откуда к ней прилетают нужные ей данные, а выпиливание асинхронщины из компоненты упрощает ее понимание.
+1
Ну получается, что все компоненты, потребляющие стор, неявно зависят от этого компонента уровнем выше. При нормальной архитектуре об этом вообще не нужно задумываться. react/rtk-query и apollo решают это проблему из коробки и правильным способом.
Все вскрылось, когда начали использовать Apollo Client, с тех пор если и использую redux - то условно только для данных, которые создаются кодом приложения "подлежат сериализации" в какой-то persistent storage (локальный, как localstorage или удаленный, как redis, aerospike, и т д )
К примеру к таким кейсам - ловил плавающий баг, запрос был в компоненте сайдбара слева. На десктопе запрос есть всё хорошо данные приходят используются в основной части приложения. На планшете сайдбар не отрисовался - запроса нет - данных нет. Сиди думай и ищи источник проблемы.
Илья, какие можешь назвать минусы эффектора (в начале ролика ты упомянул что уже все) или что из самых больших минусов по твоему мнению?
Связанность сторов, способ описания логики, то же разделение кеша, тестируемость, дебагабилити?
Знающие люди, подскажите, я может не знаю, но разве в условном Vuex такой же проблемы нет? Если мы затянули в стейт данные из одного компонента(или даже роутером, допустим), то нам по факту ничего не мешает сделать обращение к этим данным(забрать их из стейта) из другого компонента, который их не тянул.
Как раз недавно у меня на проекте появился такой компонент, который использует те же данные который подгружал другой, но я решил эту проблему вызовом экшена и в этом компоненте, так как данные могут быть не актуальны и их нужно обновить в любом случае.
Спасибо, Илья, как-то не задумывался ранее на эту тему, обычно в своих проектах оборачивал всё в один слой DataLayer и там грузил все кеш-данные, который нужны многим и так как этот самый DataLayer - это самамя верхняя компонента и в неё всё завёрнуто, то так просто её не удалить,
очень интересно и полезно, спасибо!
казалось бы, вроде очевидная вещь, но почему-то сам об этом не задумывался:)
Если потребителями данных являются несколько дочерних компонентов компонента "А", значит запрашивать их должен компонент "А". Это не недостаток Redux, это недостаток архитектуры конкретного приложения.
Очень интересно, спасибо!
Только у библиотек из данного списка будет друга проблема, это контролирование жизни кеша, в rtk-query в 0.2 версии можно только время установить, по истечению которого кеш очистится, в 0.3 можно передать callback, по которому вы сделаете очистку кеша, или в принципе кеш очистить весь, что тоже не очень удобно делать.
Проблема описанная решается так, или компоненты-дети используют данные, которые запрашивает их компонент-родитель, или, если вы не хотите перезапросы частые делать, то просто проверяете наличие данных в сторе.
а по redux-toolkit будет что?
Дока есть, там все написано уже))
@@pannihto7588 все ИТ каналы можно удалять получается вместе с книгами, по всему есть дока и спека😀
@@ivansidorov5 не совсем так. Дока доке рознь.
Но конкретно в случае RTK это пожалуй одна из самых исчерпывающих документаций, что мне встречались.
@@ivansidorov5 не все, но 90% - да
Почему на 4й минуте ты не упомянул про внутренний Redux Middleware(без Thunk/Saga)?)
Должен быть компонент, ответственный как за загрузку данных, так и за их очистку. В useEffect не зря придумали функцию очистки при return.
Если это, скажем, список юзеров и где-то рядом - статистика о загруженых юзерах, то очевидно - это компонент, содержащий их обоих.
Дергать "бесконечно быстрый интернет" это такое себе.
Можно спокойно выстроить более сложную иерархию и передавать просто id в пропсы дочерних компонентов и те будут селектором выбирать данные, никаких с этим проблем не будет, они изначально зависимые, вложенные компоненты.
Тоже самое с различными визардами. Выбирать и очищать данные будет компонент, содержащий все степы. Не нужно в степы "пихать" логику загрузки данных. Селекторы - пожалуйста.
Но бывают и особые случаи. Если мы делаем e-commerce, то список товаров по фильтрам может загружать, очищать верхний компонент, а класть товары в корзину уже будет карточка товаров самостоятельно. В нее в пропсы придут данные, чтоб она отрисовалась, но она будет диспатчить данные самостоятельно. Даже, если нужно перевыбрать товары, по какой-то причине при добавлении в корзину (например забрали последний), и это происхойдет в thunk-е или саге, которую вызовет карточка товара, и это затем подхватит верхний компонент для отрисовки всех карточек - тоже не проблема. Легко отслеживается flow, главное использовать TypeScript.
С бОльшего проблема надуманная. Надо реально быть косячным, чтоб такие зависимости сделать, как в видео.
Очень интересная тема, жду остальные видио из данной серии!
Хоть ты мне и не нравишься, но... лайк.
Красиво
По поему это очевидная проблема, любой компонент, который получает данные должен их сначала запросить. Это явно не проблема redux, а косяк разработчика, который на кнопки жмёт и мозги не включает. Но как правильно подметил автор, если три компонента будут одновременно смонтированы на страницу мы упремся в проблему дедупликации 3х одинаковых запросов. React query в этом плане это чудо какое-то, сам был ярым поклонником redux, перечитал доку до дыр, пересмотрел наверное все возможные уроки и подходы, но как увидел RQ влюбился с первого взгляда, пересел и не жалею. Кода на процентов 30 меньше, функционала из коробки больше, кастомизировать можно до бесконечности, под задачи любых сложностей, а главное забыл об одностороннем потоке выполнения flux, как о страшном сне.
Все это уже давно исправлено в Redux Toolkit.
я балдею с футболки гуся, лайк
подъехал качественный контент)
Мне кажется, это проблема не Редакс, что 1 компонента, берет данные из Редакс, и другая эти данные заполняет, но они назависимы друг от друга в коде. Я мб что-то упускаб, но почему бы в таком случае, не проверить стейт, есть ли там данные, и если нет, то запросить? Можно мне кажется в принципе организовать код так, что это будет делаться всегда, для каждого запроса. Но мб есть какие-то подводные камни. Уже давно с экосистемой Редакс не работал.
Я когда работал с NGRX никогда не дергал экшен загрузки с компонента потребителя и вообще старался сделать так чтоб этот экшен вызывался максимум один раз.
Если запрос данных не в компоненте держать, а в отдельном контроллере, который загружает все необходимые для страницы данные, то никаких фантомных связей не будет.
Возможно я привык с такой архитектурой с отдельной загрузкой данных работать конечно, но мне кажется что проблема немного преувеличена.
Но я бы с радостью послушал про инструменты, которые её решают, но при этом так же хороши в стейт-менеджменте, как redux.
ну вот хорошая серия намечается, на самом деле контента не для новичков не хватает )
спасибо. поддержу комментарием
ооочень хорошая тема!
главный недостаток redux это многословность
RTK слегка помогает сгладить этот момент
@@d3i0 Называется "Мы будем использовать луноход" там, где можно построить дорогу
а если просто управлять стором не в компоненте D, а в компоненте А. То есть загрузка происходит в компонента А, тогда как уже в дочерних компонентах будет проиходить просто получение данных из стора. В своих проектах на Nuxt я всегда стараюсь придерживаться такой политики. данные у меня запрашиваются в pages в хуках, а непосредственно уже работа с этими данными в дочерних компонентах
Интересно послушать сравнение Redux и MobX. Один реализует иммутабельный подход, второй мутабельный. В свое время был озадачен вопросом на собеседовании: "В каких приложениях лучше использовать мутабельный (mobx) и иммутабельный (redux) подход?". Так и не смог найти для себя вразумительный ответ, так как считаю, что любое приложение можно написать на любом из них.
Хорошое интро, Илья, спасибо!
Спасибо за видео, хотелось бы и про rxjs, про это совсем мало информации авторитетной.
По моему мнению, это ошибка разработчика и нарушать правило low coupling можно через любой инструмент.
Если мы с одного места получаем данные и отдаем 3 компоненту, в таком случае как мы сможем убрать зависимость с помощью какого-либо инструмента, если мы в будущем планируем убить этот компонент/фетчинг и перестать фетчить данные?
А как кэш спасет, если мы убрали фетчинг и у нас больше нет данных?
Хорошо, мы получаем данные например через react-query, добавляем в кэш и в 3 компоненте дергаем кэш. Это спасает нас? Думаю нет.
Ждем решения этой проблемы :)
Вы во всех трёх компонентах делаете фетч. Реально происходит один :)
Оооо, а я момент с кешем решил демократичными хранилищами. На вроде одно хранилище, один запрос за данными и куча экземпляров которые могут командовать, но команды демократичные, если загрузка, то одна, если ожидание ответа то ответ всем, когда загрузка закончится, если отменить загрузку, то только когда экземпляр один, все остальные будут ждать загрузку
Все используют redux как кэш, потому что даже уже на этой стадии становится понятно какой адский пайплайн-боилерплейт по всей кодовой базе приходится городить ради каждой дополнительной сущности и действия.
Состояние внутри react-компонент в 99% случаев абсолютно всех устраивает, и никакой проблемы не появляется.
Проблемы начинаются не из-за отсутствия использования redux-а, а когда его таки используют.
Илья в светлом и мирном будущем(надеюсь) хотелось бы увидеть (и услышать) твоё мнение на альтернативные Редаксу лабы по управлению состоянием и их сравнение друг с другом
Так себе проблема.
Мне вот в Redux больше всего не нравится то, что данные хранятся как дерево, а не как граф. Подобно MobX, например. Поэтому постоянно приходится совершать работу по их преобразованию, это порождает многословность.
Было бы здорово поверх редакса написать иммутабельную базу данных, где можно определить схемы, чтобы она автоматически обрабатывала связность объектов, позволяя с ними работать как с графом. Думаю, значительную долю многословности это бы убрало совмещая подходы Redux и MobX.
А в чем проблема - выразить граф в виде списка и прописать связи по айди в его элементах?
Rematch новый кандидат на замену redux-saga
А мне понравилась матрица, я раза три смотрела, чуть не писалась со смеха ))
Загружаем данные один раз на самом верху - потребляем всеми ниже расположенными компонентами. Если у вас компонент, находящийся ниже по дереву, загружает данные, потребные компоненту стоящему Выше - то Вы пососали на уровне проектирования. При любом случае ожидания данных выше чем есть на данный момент, диспатч экшона с фетчингом по дефолту должен быть вынесен выше.
Ну например есть список, для каждого элемента списка можно сделать какую-то операцию, потом список целиком надо обновить - по сути нижестоящий компонент обновляет вышестоящий и это в данном случае логично
як завжди - топ
+ за интересную тему, но это, действительно, не проблема redux
Мы требуем продолжения банкета =)
"Эта связь никак не выражена в коде". To whom how.. спорное утверждение..
Не хотел бы придираться, но изменить код так, что пропадёт загрузка каких-то данных - это явно не рефакторинг
Все пытаюсь сматчить Redux и подход, что глобальные объекты это плохо. Не вяжется у меня никак. Может кто знает и может объяснить почему Redux это хорошее решение, хотя это глобальный объект для приложения и появляются связи всего со всем?
один стор - это удобно.
Фатальный недостаток Redux это то, что его сделали не Microsoft (лурк)
Я очень рад что наконец-то люди начали осознавать что что-то блин не так во всей этой лапше собираемой поверх redux
Проблема существует. Но решается композиций компонентов. Такое часто возникает когда открываешь сайт, а он должен "прогрузить" всякие справочные данные(профиль, страны, локали и всякие там списки). И нужно это отслеживать при загрузки приложения и в правильном порядке вызывать экшена просто. Такие вещи дополнительными библиотеками мы никогда не решали. Мне кажется что в некоторых случаях бессмысленно надстройки еще включать если архитектура приложения уже хаос.
Если я все правильно понял, то это видео про то что кэш нам поможет решить проблему с двойной загрузкой данных, если комопненты и B и D будут сами загружать данные. Слишком хайпово назвали "Фатальный недостаток Redux ;)" смайлик конечно к месту =). Подписался на канал жду еще видео, спасибо за работу и интересный подход с рисованием на планшете
Ну не знаю, мне кажется самая идея вот этого стора - есть в том что компоненту "B" стрго пофиг откуда в сторе данные. Как говорится, на то он и единый стор.... А то если как - то показывать эти засисимости компоненов друг от друга то сложность этих связей быстро растет. Да, есть определенные вопросы, но это же как раз и есть "побочный" эффект от упрощения утравления данными...
Ну он наверное очевиден при огромном приложении, но правится легко же), на то и рефакторинг)) но интересное наблюдение)
Не очень понятно, что в данной ситуации смущает и в чем недостаток.
Неявной связи B - D таки нет.
Есть явная связь B - store. Кто, откуда, когда и как обновит store нам плевать. Если мы удалим D у нас абсолютно ничего не поменяется и не сломается. В store будет init.state, в котором, очевидно, будут данные для B.
Другой вопрос, что по-хорошему, зависимость от store надо бы делегировать, скажем компоненту A, который будет выступать медиатором.
Ждём следующие выпуски с раскрытием темы
Идеальная ситуация когда данные поступают из одного источника А и передаются компонентам ниже.
Но когда компоненты ниже А начинают менять данные для него, это и есть повод для бесконечных рассуждений 😁
@@alexs7931 они так или иначе будут это делать. Либо явно, либо нет (оповещая делегата А обновить данные)
"Кто, откуда, когда и как обновит store нам плевать" - чего то совсем уж упрощено. Компоненты которые получают данные на входе действительно все равно откуда эти данные пришли. Но когда мы берем данные с состояния нам придется заморочиться как они туда попали, и есть ли они там вообще.
Модель была бы красивой если бы реально все данные были в нашем store. Но в веб как правило как раз ничего нет, частичные снимки предоставляет бекенд по запросам. Как на меня, сложность организации загрузки этих данных по требованиям компонентов превосходит по сложности сам redux (особенно "радует" что часто разные запросы к бекенду дают одни и те же объекты в разной степени детализации, то все держать в store в синхронизированном виде весело)
@@ОлегМакарчук-о9р Упрощённо для привлечения внимания, "чем проще тема, тем больше экспертов", на канале в одном из видео подсмотрел 😁
@@ОлегМакарчук-о9р "как они туда попали" странно, что у вас могут возникнуть такие вопросы. Так или иначе через делегата, который таки должен заниматься инвалидацией и соблюдением контракта. В таком случае, не очень понятно, зачем вам знать, кто выпустил валидный контракт.
Круто!
У меня в проекте экшоны вьюкса чаще всего дергаются хуками роутера.
А если какие-то компоненты хотят дергать экшоны из себя, то это либо корневые, либо ui компоненты.
Избегайте говнокода
Придумайте себе правила и строго их придерживайтесь :)
Я просто оставлю это здесь 😀 th-cam.com/video/XEt09iK8IXs/w-d-xo.html
PS. Когда-то столкнувшись с проблемой описаной в ролике закончил написанием своего криввенького кеш менеджера).
Первое что пришло в голову во время обсуждения - завести/написать инструмент, который будет при обращении к данным либо грузить их с сервера, либо с кеша) компоненту по сути лучше вобще не знать как к нему попадут данные))
еще бы иммутабельность упомянуть, которая на больших проектах создает большой мемори трафик и головную боль для GC
Immer
посмотрел свои проекты, радуюсь что не так много фантомных связей между компонентами, хотя к сожалению не везде
жду видео про мобкс, крутое видео
Проблема притянута за уши.
Очень интересно про GraphQL API / Apollo & Redux. Безумная путаница в просторах интернета, в одних источниках кричат, что удаляем Redux - устанавливаем GraphQL, в других говорят что Redux и GraphQL про разное и их можно использовать совместно. Во первых новичку и так не просто вклиниваться в поток, так еще и про технологи в каждой статье и на каждом канале говорят так уверенно, что начинаешь теряться в силу своей неопытности.
Apollo и Redux про разное, но все же это пересекающиеся множества. Особенно когда redux используется по большему счету как кэш + состояние "грузится/загрузилось/ошибка". В таких случаях gql в лице apollo может безболезненно заменить redux.
Есть ещё одна большая проблема в Redux, допустим есть некая лента из 400 элементов, и эти элементы хранятся в сторе, при попытке изменить один элемент, допустим поставить лайк, придётся перезаписывать весь обьект, как по мне это одна из самых больших проблем.Redux не подходит для работы с большими обьёмами данных, по этому я препочитаю MobX. ибо он более лаконичен и позволяет не перезаписывать все данные при попытке изменения одного поля, да и реактивность достаточно приятная штука.
P.s. Открыт к дискусии)
Попробуй immerjs
попробуйте rtk и в особенности immerjs, который там в комплекте с редьюсерах идет - больше никакого головняка при работе с глубокими вложенностями или изменением каких-то массивов.
@@theghostminsk спасибо за совет,посмотрю)
А зачем 400 элементов хранятся в сторе на ФРОНТЕНДЕ?
Чтобы избежать этой проблемы необходимо создавать компоненты- контейнеры, которые должны диспатчить все экшены и подключаться к стору. В данном примере это компонент А. Вся логика работы со стором должна хранится там
С появлением хуков стало заманчиво использовать диспатч на нижних уровнях вложенности. Илья привел отличный пример, что из этого может выйти
А я наоборот сторонник загрузки данных максимально близко к месту потребления
Хорошо бы было если б автор сказал , а вот используя такие стэйт менеджеры …. У нас нет такой проблемы. Хотя для меня лично все перечисленное выше не проблема.
Да и в редаксе сейчас нет такой проблемы с приходом rtk-query. Правда видео, очевидно, затравочка и решения будут освещены позже. )
отличное кликбейтное название
вынес для себя, что фатальный недостаток redux - это, внезапно, разработчики, которые вносят неявные зависимости в код. но, к сожалению, от таких проблем спасет разве что wix/тильда
а так да, если пальцы в розетку засунуть - будет бобо. другое дело, являются ли любители совать пальцы в розетки ФАТАЛЬНЫМ НЕДОСТАТКОМ розеток?
Много однотипных комментариев, но этот с метафорой про розетку, отвечу.
Точно так же как дизайн розетки эффективно МЕШАЕТ совать пальцы, точно так же хорошее архитектурное решение своей архитектурой мешает делать плохо. У питона это называют to fall into the pit of success.
Поэтому да, если бы розеткой можно было бы легко ударить себя током и если бы много кто это делал - это было бы фатальным недостатком розетки
@@JavaScriptNinja из документации:
>Redux is a tiny library
по-идее, чтобы tiny library превратилась в архитектурное решение, которое будет в состоянии помешать кому-то делать плохо, ей стоит обрасти принципами и подходами, как минимум
идея же о том, что на столько сильное зацепление компонентов - это плохо, как по мне, довольно проста и вполне претендует на роль одного из таких принципов. и если мы допускаем такие ошибки при проектировании, довольно легкомысленно будет ждать спасения от react query, akita, recoil, apollo, relay, mobx, чего-угодно. вот wix - да, с ним шансы есть
надеюсь мой комментарий был выбран не для того, чтобы сместить обсуждение на метафору
@@oleksandrh3994 принципы и подходы не помогают остановить в делании плохо. Это надстройка. А я говорю о базисе
@@JavaScriptNinja очень интересное утверждение, зачем же тогда они нужны?
понимание, как делать не (не)надо и есть тем самым базисом, который не даст нам отстрелить себе колени с последующими обвинениями ужасной технологии, которая нам все сломала.
у нас же все-таки не просто так есть прокладка между клавиатурой и либами/фреймворками. а то бы нас уже no-code давно заменил
@@oleksandrh3994 все очень просто - в контексте бизнес-проекта (когда мы пишем прикладной код а не системный) программист должен быть сосредоточен на решении бизнес задач. Чем меньше ему необходимо знать вещей, которые невыразимы в коде и неконтролируемы автоматически - тем эффективнее будет работа.
Конвенции и архитектурные решения не имеющие воплощения в коде приводят к задержкам на код-ревью, многократно подтверждено гитлабом
какая то выдуманная, притянутая проблема, обоснованная частным абстрактным случаем, ни о чем.
то как ты строишь поток данных между компонентами через стор, это только дело твоих рук и в этом нет вины редакса, короче тема уровня инфоцыганства
значит не я один так подумал
Я с такой проблемой не раз сталкивался. Особенно в больших проектах, данные ошибки съедает много времени (там таких не явных связей может быть несколько).
Здесь говорилось больше про то, что подход Redux и его аналогов, не защищает от таких рода ошибок, и этим часто грешат разработчики до конца не разобравшиехся в инструментарии.
Это всё равно что назвать rust инфоциганским языком, только потому что некоторые разработчики не могут готовить С++.
P.S Спойлер, вообще-то все.
Использую эффектор, самое то для построения дата флоу, реактивные примиты которые являются нодами графа
А там что, нет такой же проблемы? 😂
"фатальный недостаток" это термин, который означает неприятие чужого кода (разработки) в силу каких то причин. В этом ролике не про то ... и как по мне, все очень заумно, возможно и правильно судя по комментариям, но я ниче не понял)))
Все что я услышал, это не недостаток редакса, а не правильная архитектура приложения:) все легко решается. чем мне нравится редакс, что он не делает магии, есть простые чистые функции, которые легко покрываются тестами.
Я могу быть неправ но вроде как скрытой зависимости можно избежать используя либу reselect.
+ мне кажется когда компонент В использует тот же стейт что и D, но они не связаны и в разных местах приложения. Не логично ли сделать либо
1) Вызвать loadUsers где то выше, у родителя.
2) Вызвать loadUsers у обоих при монтировании компонента.
UPD: досмотрел до конца. хммм ну возможно стоит чекнуть эти либы, но если честно есть ощущение что логика будет более туманна в таком случае.
Как ты и сказал, магически будут работать.
reselect отдельно не нужно, если пользоваться rtk. А пользоваться redux и не пользоваться rtk - странно.
Про CombineReducers и разделение стейта на куски видимо вы не в курсе. Также как про то, что инициацию получения данных лучше делать в зависимости от событий раутинга. Объяснять рукожопость программера минусами библиотеки - такой себе ризонинг.
Улетает в копилку знаний.
как ниже заметили - это не недостаток стейт менеджера, а косяк тех, кто дизайнил приложение. Так же, как и распространенная ошибка складывать в стейт локальное состояние, ошибка дева, а не вина стора. Редакс меня миновал на реакте, а вот ngrx и vuex на ангулар и вуй зацепили. Из того, что не понравилось помимо упомянутых ошибок самих разработчиков - то, что сторы заставляют писать прямо таки дофигище текста ради простой вещи.
Спасибо за упоминание локального состояния. К примеру есть модальное окно у которого есть состояние show/hide где правильно хранить и изменять данное состояние? И почему?
@@ev_geniy17 в обычно ситуации вы, наверное, хотите видеть show/hide в качестве пропсов/инпутов для своей модалки т.е прокидываете значения из родителя.
@@dmytroputrin980 получается что состояние хранится в компоненте модалки, но зависит от пропсов и где-то в сторе компонента родителя будет действие и состояние которое будет менять пропсы для модалки
@@ev_geniy17 да, в идеале `showModal` как раз и будет браться из локального состояния родителя. Есть куча вариантов сделать доступность вызова глобальным аля через сервис или даже сторе, но с этими подходами лично у меня всегда было больше проблем, чем выгоды.
D запрашивает данные, B их отображает. Какой смысл сохранения компонента B, если данные не будут запрашиваться в D, а сам компонент B является тупым, просто отображая поступившие данные
В нормальных проектах эти компоненты явно связаны по средствам вызова компонента B в компоненте D с передачей пропса с данными
А я думал ток для патронов)
Ну понятно, через 2 недели
Проблема очень просто решается. Нужно помимо переменной users: User[] иметь переменную isUsersLoaded: boolean.
Компонент B и D проверяют isUsersLoaded: если false, грузят данные; если true, берут из стора.
В идеале, конечно, эту логику должна в фоне делать библиотека для загрузки данных, чтобы вручную не пилить в два раза больше переменных. Не в курсе, есть ли такой функционал в react-query, swr и т.п.
А можно без заставок, зачем тратить мое время на перемотку?
На 10.50 полнейший бред с недостатком, не выдержал смотреть эт до конца. Все зависит от того, каким образом вы строите архитектуру. Если кривые руки, то естественно будуте ныть, что мол недостатки
Матрица 4, стоящий фильм если конечно понять задумку автора.
Во фронтенде большинство технологий плюс-минус одинаковые. К чему постоянно вот этот пафос - непонятно.
Чуваки, идите куда-нибудь в геймдев, становитесь экспертами там(но вы не пойдете, потому что сложна и порог входа выше в десяток раз).
а зарплаты меньше
У фронтов слегка надуманные проблемы)))
Можно же кешить на стороне сервера,
если не хочется трафик гонять, то почему не сделать Класс для работы с апи, который и будет Кешить что нужно, а что нет.
Фронтеры почему-то не хотят кодить: то только думают как использовать что-то готовое, которое вообще не подходит под решение задачи? =))
да мы убогие, забей
@@kulikoffAS ахахах ;)
Спасибо за контент. Офигительный звук, думал его вообще не возможно достойно настроить под линухом
Так он под виндой)
@@easymoneydamnsniper Тогда не чудо)
Redux - это и есть один сплошной фатальный недостаток.
Я не соглашусь
@@JavaScriptNinja Если честно, хотелось бы больше послушать про достоинства редакса перед другими библиотеками. А то недостатков у него и так полно
angularjs тоже все хейтили в свое время
Есть еще одна проблема редакса, связанная с описанной в видео. Она заключается в том, что мы не знаем, КОГДА данные для потребления будут доставлены. Допустим, компонент B знает, что D загрузит данные, но он не знает, когда это случится. И если просто завяжется на эти данные, то мы можем иметь неприятные эффекты, как 1) мерцание UI (сначала отрендерилось одно, потом другое 2) повторный рендеринг (что плохо влияет на производительность 3) иногда ошибки в вычислениях внутри компонента. Как уже заметили выше, частично эта проблема решается организацией архитектуры. То есть ты видишь, что компонент D грузит данные и понимаешь, что удалять его нельзя :)) но все равно могут происходить неприятные моменты из-за того, что другие компоненты, например, могут дергать экшены стора через D
Как мне кажется Redux создавался ещё в те времена, когда активно использовался jquery, как рендер html 🤣. Хватило бы и react, но мы же не стоим на месте.
И когда пациент скончается? Пока живее всех живых.
Пациент обрёл новую жизнь вместе с Redux Toolkit и Redux Toolkit Query
Ну, парни проект не забрасывают, усовершенствуют...
думаю когда будет сравнимая по мощности экосистема)
@@pannihto7588 то что мертво умереть не может :D а вообще - да, RTK сделал redux по крайне-мере хотябы немножко юзабельным