Начал изучать компоуз. Второй день. Пока не очень понятно че там как с фрагментами и навигацией и что под капотом у компоузов. Спасибо тебе за твой вклад, гляну код, попробую разобраться
Спасибо за разборы! По твоем проектам и по примерам гугла (owl, с твоей наводки) начало получаться делать ui на compose c jetpack navigation. Выглядит как то, что будет в большинстве проектов через пару лет
Спасибо за очередное крутое видео Алексей и за крутой доклад на конференции в Омске, было очень много полезной информации! Рад был познакомится, спасибо тебе за твою открытость и простоту, ждем в следующем году!
Алексей, ты всегда говоришь про LiveData потому что есть observeAsState, но ведь еще StateFlow/SharedFlow и collectAsState. У нас на проекте, конечно под наши нужды, сделано как раз так. И MVI модель немного расширена. У нас есть Action, глобальное действие засылаемое во ViewModel, есть Event (тоже через Flow, для UI, обрабатывается в Composable через LaunchedEffect), есть Result (то что выдает ViewModel, и в данном случае Event это тоже Result), и собственно отдельный Reducer, который обрабатывает именно Result для изменения состояния. Event тоже сделан как Result, для того чтобы его можно было выдать из ViewModel, но при этом, при обработке Flow, такие сообщения перенаправляются в другой канал (eventFlow) и не попадают в reducer. Ну и конечно сама модель: _state как MutableStateFlow, event, action как SharedFlow. Было бы интересно услышать твое мнение на подобную архитектуру. Ее не я придумывал, и хотелось бы другое мнение, избыточна ли такая архитектура или нет
Ваш вариант более современный, недавно на медиуме похожее видел. Тут видео 2х годичной давности. По-хорошему вообще вью модельки надо убирать, как по мне
Алексей, я правильно понял, что вы модель в архитектуре mvi распили на части при помощи sealed-класса превратив таким образом состояние представления в набор событий по изменению ui? В моём понимании такая оптимизация превратила mvi в mvvm. Просто Дорфман в своё время акцентировал внимание на том, что модель по структуре должна быть полноценной и достаточной для построения ui в любой момент времени. Точнее, модель должна быть полной, неизменяемой и подписка на её изменение должна быть только в одном месте. Только такой набор качеств гарантирует согласованность между состоянием интерфейса пользователя и состоянием бизнес логики. Тот пример, который вы привели в качестве сложности копирования полноценной модели я решаю простой инкапсуляцией. Для приведенного вами примера я бы создал методы state.copyToLoading(), state.copyToData(values: List) и state.copyToError(th). Разовые же события, которые вы назвали Action-ами, в mvi называются side effects и их суть не том, чтобы разгрузить модель, а в том, чтобы при изменении конфигурации они повторно не появлялись на экране. Это легко решается котлиновскими Channel-ами.
Хороший комментарий, не согласен про MVVM, так как основная идея MVI в непротиворечивости стейта. Мой вариант от вашего не сильно отличается, просто у меня это силд классы. Можно было бы сделать точно такой же дата класс и внутри хранить одно из полей в силд классе, тогда было бы прям 1 в 1. Тогда как MVVM эт посто набор полей, которые очень даже могут быть противоречивыми. У меня же стейт всегда один Идея с extension функциями над стейтом интересная (я правильно понимаю, что это самописные extension функции?) Чтоб не путать с сайд эффектами в Компоузе я пытался объяснить их как одноразовые экшны. Через компоуз сайд эффекты это не всегда можно реализовать так как иногда они генерятся в ходе работы евента, который плюс ко всему ещё и может обрастать аналитикой и ещё много чем Надеюсь, понятно объяснил
@@MobileDeveloper Спасибо за разьяснение, ваш подход стал более понятен, но некоторые вопросы всё таки остались. Если бы в примере использовался классический подход с xml-интерфейсом, то разделение модели на sealed классы сводилось бы к частичному обновлению ui и могло потенциально привести к несогласованности состояний интерфейса и бизнес логики. А учитывая, что используется compose и интерфейс фактически перестраивается каждый раз заново, то такой риск невилируется самой библиотекой. Получается цель mvi как архитектуры частично решается самой библиотекой - она сверяет новую dsl структуру с текущим состоянием ui и перестраивает разницу. Меня смущает, что разделение модели по sealed классам побочно определяет какому экрану какие данные нужны. Точнее даже какому состоянию экрана какие данные нужны. К примеру, если завтра при обновлении списка понадобится одновременно показывать уже загруженные данные и индикатор загрузки, придется переделывать и модель экрана т.е. sealed-класс и compose функцию. Если бы всё было в одном data классе, то достаточно было бы изменить только момент загрузки, где loading переключается с false на true. При условии, что compose функция изначально написана достаточно универсально. Получается, что модель берёт на себя часть ответственности за отрисовку, а не просто предосталяет данные для обновления интерфейса. Несогласованность данных внутри модели это палка о двух концах. С одной стороны это может быть ошибка разработчика по невнимательности, а с другой стороны стать со временем бизнес фичей. Я борюсь с человеческим фактором extension функциями модели, вы решаете это sealed-классами. Просто два разных подхода. Мне видится так, что ваш подход с sealed-классами более элегантен с точки зрения программирования, но имеет потенциальные риски в рефакторинге, при условии, конечно, что будет использоваться именно compose библиотека, которая берёт на себя задачу согласования состояний.
Спасибо за видео. У меня вопрос, касаемо функции obtainEvent. В чем ценность подхода при котором у нас во ViewModel только один вход - obtainEvent, который внутри разводится через switch на несколько функций. Почему из View просто не вызывать нужную публичную функцию ViewModel-и, которая уже дальше создаст нужный state. Не кажется ли, что при данном подходе есть некоторая избыточность? Разве public-функций ViewModel-и не было бы достаточно?
Там не факт что не будет сразу же перехода в нужный стейт прям из obtainEvent. Плюс позволяет инкапсулировать какие-то функции. какие-то переиспользовать сразу же с нужным набором параметров, не накладывания на вью логику. Например, у вас есть функция fetchItems(count: Int, start: Int, filters: [Int]) и как вы ее будете из вью вызывать? Там нужно запоминать какое количество уже есть, с какого начинаем, какие фильтры. Все это должно храниться во вью модели, причем для евента скажем FetchInitial это будет параметры 0, 0, [], а для FetchMore 20, 1000212, [0, 1]. Вам либо логику придется частично во вью переносить (что плохо), либо через obtainEvent. В общем функция приватная не всегда 1 к 1 соотносится с евентом и в этом основная причина
Верно, но что мешает сделать публичные функции без параметров fetchInitial и fetchMore, которые будут вызываться на стороне View, а эти функции в свою очередь будут вызывать приватную fetchItems с нужными параметрами? Тогда мы просто избавимся от набора sealed data классов.
А где начало всего этого? Если я только начинаю с чего начинать? как написать первое приложение и понять все эти вью и тд? Есть отдельный плейлист типа андроид студио начало? 😅
Спасибо за видео, но для продакшена compose не кажется готовым. На что указывают experimental аннотации в том числе. Попробовал твой проект, при переключении всё моргает как новогодняя ёлка. Есть глюк, после повторного нажатия на Settings экран становится белый и табки перестают отвечать. Но в его будущее я, всё-же верю.
Смотри, баг с навигацией это не компоуз, а мои руки кривые)) я поправлю это в ближайшем релизе. То, что он моргает это аналогично мои кривые руки и чуть-чуть компоуза. В частности это рипл эффект, который по умолчанию вешается на любой clickable. Сделать noRippleEffectClickable это пять минут. Тоже поправлю в ближайшее время ) Но это право каждого же ) я считаю готов, но не могу и не имею желания кого-то принуждать ))
Ребятки, хочу сделать небольшую ремарку к своему комменту. Не смотря на то что ещё используются аннотации experimental, пробовать и изучать compose однозначно стоит. Поскольку уже очень скоро experimental уберут и спрос на эту технологию стремительно начнёт рост.
Кстати, я посмотрел почему моргает при переключении. Дело в том, что навхост по умолчанию имеет включённый Crossfade эффект (что довольно тупо, но как есть). Можно взять такой же навхост без анимации, но из аккомпаниста и тогда моргать не будет )
Подскажите пожалуйста, умные люди в какую сторону покопать. Мне нужно сделать карту, типа дерева во все стороны. Её нужно будет скролить в любую сторону, с подгрузкой объектов. Какой то дефолтный компонент может взять за основу или ещё что то. Спасибо! Всем печенье!
А как тестировать такие viewModel? Пока что возникают проблемы. Вроде указал все правила для корутин, на live data подписываюсь через расширение от гугла
Я где-то читал, что аннотация @Preview не создана для просмотра всего экрана, а лишь для @Composable функций, куда передаётся не ViewModel, а уже, просто, данные из State. Таким образом превью работает всегда.
Спасибо за видео! А где самый последний вариант кода посмотреть? в репе на гитхабе нет ничего того, что на видео реализуется, а имеено SupportScreen и иже с ним
Спасибо большое за видео. Буду пытаться затащить к себе твой подход. Разве что я считаю, что Intent все же больше подходит, чем Event. Для меня Event это больше про то, что мы должны из VM что-то прокинуть в UI для пользователя, а не наоборот. Хотелось бы узнать твое мнение насчет таких штуковин как SnackBar и Toast. Как они укладываются в MVI? Это же single event. Показал и забыл. Нужен небольшой аддон к твоему видео :)
Забыл уже, если честно, показывал я там это или нет, но в проде у нас есть отдельный sharedflow для работы с экшнами ) здесь можно завести SinglealiveAction для этого
@@MobileDeveloper а как вы обходите засылку двух одинаковых ивентов в sharedFlow? Оборачиваете, например, bool в класс обертку Event? Мне пришлось для этого сделать Channel
Для такого сценария лучше использовать StateFlow) у нас засылка двух одинаковых экшнов валидная ситуация. Мы делаем replayCache в одно событие просто, чтоб оно не проигрывало дважды одно и тоже, но мы можем заслать одинаковые экшны (например toasty тот же) а StateFlow такое фильтрует автоматом )
У меня довольно похожий подход с mvi и разбивкой на стейты. Есть 3 стандартных стэйта - прогресс, ошибка, данные. И этот Стейт хранится в лайвдате: вроде круто, всегда вытягивается последнее состояние. Но!!! Если есть кейс в котором последнее состояние перед укладкой фрагмента в бэкстек - прогресс (например что то отправить и уйти на другой экран), то после возврата обратно на фрагмент приходится заново данные перезагружать ибо иначе будет висеть старый Стейт - прогресс. А вроде как не хочется. Не понимаю пока как правильно обработать такой Кейс.
Если данные из локалки, то в целом не вижу ничего страшного, но конкретно на этот случай, можно не использовать sealed class и хранить все в одном data class, а там соответственно будет поле с данными и поле isProgress, тогда достаточно будет только флаг сбросить
Спасибо за видос, как всегда довольно понятно. Я один вижу как мерцает экран при каждом переходе? Выглядит так, будто вначале отрисовывается белый пустой экран, а потом вызывается composable функция
Тут сразу по нескольким причинам. 1 - к этому привыкли люди и у многих проекты выстроены на вьюмодели и моя задача была показать, что можно оставаться на ней, используя компоуз. 2 - В целом, если проект небольшой, то какая разница как ты это назовешь VM или Interactor ) смысл от этого не сильно поменяется ) А где-то это все объединять нужно, потому что так проще работать командой
"Рожание" нового стейта убивает весь смысл компоуза (который состоит в том, чтобы рекомпозировать только те части, на которые повлияли конкретные переменные вью-модели). Тут же получается, что при любом чихе будет рекомпозироваться ВСЁ
Автору спасибо. Вестоским желаю терпения
Начал изучать компоуз. Второй день. Пока не очень понятно че там как с фрагментами и навигацией и что под капотом у компоузов. Спасибо тебе за твой вклад, гляну код, попробую разобраться
Андрюха! Ты тута?! Ахахаа и я тута!
Топовые видео, спасибо, разъяснил много сильных моментов на которые я искал ответы
Спасибо за разборы! По твоем проектам и по примерам гугла (owl, с твоей наводки) начало получаться делать ui на compose c jetpack navigation. Выглядит как то, что будет в большинстве проектов через пару лет
Думаю да это некий будущий стандарт )
Ну как там, во всех проектах? Объективно MVI полное дно, MVVM + State подход намного лучше и понятнее.
Огонь, так держать. Много полезного)
Спасибо )
Блин это очень круто! Спасибо!
Видео просто ТОП! Очень полезно, Спасибо!
Спасибо. Материал - топ!
Пожалуйста )
Спасибо за очередное крутое видео Алексей и за крутой доклад на конференции в Омске, было очень много полезной информации! Рад был познакомится, спасибо тебе за твою открытость и простоту, ждем в следующем году!
Спасибо большое) с удовольствием приеду ещё раз )
Можно ли как-то посмотреть запись этого доклада?
@@СергейПанов-з3ц не думаю что в общем доступе он скоро появится(
Выложу на канале как только мне отдадут видео )
Спасибо. Полезно.
Круто! Спасибо
очень очень круто. спасибо тебе за такое класное видео. ждем еще про compose и архитектуру
👍👍
Алексей, ты всегда говоришь про LiveData потому что есть observeAsState, но ведь еще StateFlow/SharedFlow и collectAsState. У нас на проекте, конечно под наши нужды, сделано как раз так. И MVI модель немного расширена. У нас есть Action, глобальное действие засылаемое во ViewModel, есть Event (тоже через Flow, для UI, обрабатывается в Composable через LaunchedEffect), есть Result (то что выдает ViewModel, и в данном случае Event это тоже Result), и собственно отдельный Reducer, который обрабатывает именно Result для изменения состояния. Event тоже сделан как Result, для того чтобы его можно было выдать из ViewModel, но при этом, при обработке Flow, такие сообщения перенаправляются в другой канал (eventFlow) и не попадают в reducer. Ну и конечно сама модель: _state как MutableStateFlow, event, action как SharedFlow. Было бы интересно услышать твое мнение на подобную архитектуру. Ее не я придумывал, и хотелось бы другое мнение, избыточна ли такая архитектура или нет
Ваш вариант более современный, недавно на медиуме похожее видел. Тут видео 2х годичной давности. По-хорошему вообще вью модельки надо убирать, как по мне
Спасибо!
Спасибо за поддержку канала!
Алексей, я правильно понял, что вы модель в архитектуре mvi распили на части при помощи sealed-класса превратив таким образом состояние представления в набор событий по изменению ui? В моём понимании такая оптимизация превратила mvi в mvvm.
Просто Дорфман в своё время акцентировал внимание на том, что модель по структуре должна быть полноценной и достаточной для построения ui в любой момент времени.
Точнее, модель должна быть полной, неизменяемой и подписка на её изменение должна быть только в одном месте. Только такой набор качеств гарантирует согласованность между состоянием интерфейса пользователя и состоянием бизнес логики.
Тот пример, который вы привели в качестве сложности копирования полноценной модели я решаю простой инкапсуляцией.
Для приведенного вами примера я бы создал методы state.copyToLoading(), state.copyToData(values: List) и state.copyToError(th).
Разовые же события, которые вы назвали Action-ами, в mvi называются side effects и их суть не том, чтобы разгрузить модель,
а в том, чтобы при изменении конфигурации они повторно не появлялись на экране. Это легко решается котлиновскими Channel-ами.
Хороший комментарий, не согласен про MVVM, так как основная идея MVI в непротиворечивости стейта. Мой вариант от вашего не сильно отличается, просто у меня это силд классы. Можно было бы сделать точно такой же дата класс и внутри хранить одно из полей в силд классе, тогда было бы прям 1 в 1. Тогда как MVVM эт посто набор полей, которые очень даже могут быть противоречивыми. У меня же стейт всегда один
Идея с extension функциями над стейтом интересная (я правильно понимаю, что это самописные extension функции?)
Чтоб не путать с сайд эффектами в Компоузе я пытался объяснить их как одноразовые экшны. Через компоуз сайд эффекты это не всегда можно реализовать так как иногда они генерятся в ходе работы евента, который плюс ко всему ещё и может обрастать аналитикой и ещё много чем
Надеюсь, понятно объяснил
@@MobileDeveloper Спасибо за разьяснение, ваш подход стал более понятен, но некоторые вопросы всё таки остались.
Если бы в примере использовался классический подход с xml-интерфейсом, то разделение модели на sealed классы сводилось бы к частичному обновлению ui и могло потенциально привести к несогласованности состояний интерфейса и бизнес логики. А учитывая, что используется compose и интерфейс фактически перестраивается каждый раз заново, то такой риск невилируется самой библиотекой. Получается цель mvi как архитектуры частично решается самой библиотекой - она сверяет новую dsl структуру с текущим состоянием ui и перестраивает разницу.
Меня смущает, что разделение модели по sealed классам побочно определяет какому экрану какие данные нужны. Точнее даже какому состоянию экрана какие данные нужны. К примеру, если завтра при обновлении списка понадобится одновременно показывать уже загруженные данные и индикатор загрузки, придется переделывать и модель экрана т.е. sealed-класс и compose функцию. Если бы всё было в одном data классе, то достаточно было бы изменить только момент загрузки, где loading переключается с false на true. При условии, что compose функция изначально написана достаточно универсально.
Получается, что модель берёт на себя часть ответственности за отрисовку, а не просто предосталяет данные для обновления интерфейса.
Несогласованность данных внутри модели это палка о двух концах. С одной стороны это может быть ошибка разработчика по невнимательности, а с другой стороны стать со временем бизнес фичей. Я борюсь с человеческим фактором extension функциями модели, вы решаете это sealed-классами. Просто два разных подхода.
Мне видится так, что ваш подход с sealed-классами более элегантен с точки зрения программирования, но имеет потенциальные риски в рефакторинге, при условии, конечно, что будет использоваться именно compose библиотека, которая берёт на себя задачу согласования состояний.
Спасибо за видео. У меня вопрос, касаемо функции obtainEvent. В чем ценность подхода при котором у нас во ViewModel только один вход - obtainEvent, который внутри разводится через switch на несколько функций. Почему из View просто не вызывать нужную публичную функцию ViewModel-и, которая уже дальше создаст нужный state. Не кажется ли, что при данном подходе есть некоторая избыточность? Разве public-функций ViewModel-и не было бы достаточно?
Там не факт что не будет сразу же перехода в нужный стейт прям из obtainEvent. Плюс позволяет инкапсулировать какие-то функции. какие-то переиспользовать сразу же с нужным набором параметров, не накладывания на вью логику. Например, у вас есть функция fetchItems(count: Int, start: Int, filters: [Int]) и как вы ее будете из вью вызывать? Там нужно запоминать какое количество уже есть, с какого начинаем, какие фильтры. Все это должно храниться во вью модели, причем для евента скажем FetchInitial это будет параметры 0, 0, [], а для FetchMore 20, 1000212, [0, 1]. Вам либо логику придется частично во вью переносить (что плохо), либо через obtainEvent. В общем функция приватная не всегда 1 к 1 соотносится с евентом и в этом основная причина
Верно, но что мешает сделать публичные функции без параметров fetchInitial и fetchMore, которые будут вызываться на стороне View, а эти функции в свою очередь будут вызывать приватную fetchItems с нужными параметрами? Тогда мы просто избавимся от набора sealed data классов.
А где начало всего этого? Если я только начинаю с чего начинать? как написать первое приложение и понять все эти вью и тд? Есть отдельный плейлист типа андроид студио начало? 😅
Спасибо за видео, но для продакшена compose не кажется готовым. На что указывают experimental аннотации в том числе. Попробовал твой проект, при переключении всё моргает как новогодняя ёлка. Есть глюк, после повторного нажатия на Settings экран становится белый и табки перестают отвечать. Но в его будущее я, всё-же верю.
Смотри, баг с навигацией это не компоуз, а мои руки кривые)) я поправлю это в ближайшем релизе.
То, что он моргает это аналогично мои кривые руки и чуть-чуть компоуза. В частности это рипл эффект, который по умолчанию вешается на любой clickable. Сделать noRippleEffectClickable это пять минут. Тоже поправлю в ближайшее время )
Но это право каждого же ) я считаю готов, но не могу и не имею желания кого-то принуждать ))
Ребятки, хочу сделать небольшую ремарку к своему комменту. Не смотря на то что ещё используются аннотации experimental, пробовать и изучать compose однозначно стоит. Поскольку уже очень скоро experimental уберут и спрос на эту технологию стремительно начнёт рост.
Кстати, я посмотрел почему моргает при переключении.
Дело в том, что навхост по умолчанию имеет включённый Crossfade эффект (что довольно тупо, но как есть). Можно взять такой же навхост без анимации, но из аккомпаниста и тогда моргать не будет )
Подскажите пожалуйста, умные люди в какую сторону покопать. Мне нужно сделать карту, типа дерева во все стороны. Её нужно будет скролить в любую сторону, с подгрузкой объектов. Какой то дефолтный компонент может взять за основу или ещё что то. Спасибо! Всем печенье!
А как тестировать такие viewModel? Пока что возникают проблемы. Вроде указал все правила для корутин, на live data подписываюсь через расширение от гугла
Что там за революция то с инапами?) что за либа?)
требую :D
Я где-то читал, что аннотация @Preview не создана для просмотра всего экрана, а лишь для @Composable функций, куда передаётся не ViewModel, а уже, просто, данные из State. Таким образом превью работает всегда.
Ну да, так оно и есть, поэтому я и выделяю вью в отдельную функцию с уже готовым стейтом
Спасибо за видео!
А где самый последний вариант кода посмотреть? в репе на гитхабе нет ничего того, что на видео реализуется, а имеено SupportScreen и иже с ним
Я ее случайно стёр :( ну в смысле ветку эту, но вью модели есть и в других экранах в проекте
Спасибо большое за видео. Буду пытаться затащить к себе твой подход. Разве что я считаю, что Intent все же больше подходит, чем Event. Для меня Event это больше про то, что мы должны из VM что-то прокинуть в UI для пользователя, а не наоборот. Хотелось бы узнать твое мнение насчет таких штуковин как SnackBar и Toast. Как они укладываются в MVI? Это же single event. Показал и забыл. Нужен небольшой аддон к твоему видео :)
Забыл уже, если честно, показывал я там это или нет, но в проде у нас есть отдельный sharedflow для работы с экшнами ) здесь можно завести SinglealiveAction для этого
@@MobileDeveloper а как вы обходите засылку двух одинаковых ивентов в sharedFlow? Оборачиваете, например, bool в класс обертку Event? Мне пришлось для этого сделать Channel
Для такого сценария лучше использовать StateFlow) у нас засылка двух одинаковых экшнов валидная ситуация. Мы делаем replayCache в одно событие просто, чтоб оно не проигрывало дважды одно и тоже, но мы можем заслать одинаковые экшны (например toasty тот же) а StateFlow такое фильтрует автоматом )
У меня довольно похожий подход с mvi и разбивкой на стейты. Есть 3 стандартных стэйта - прогресс, ошибка, данные. И этот Стейт хранится в лайвдате: вроде круто, всегда вытягивается последнее состояние. Но!!! Если есть кейс в котором последнее состояние перед укладкой фрагмента в бэкстек - прогресс (например что то отправить и уйти на другой экран), то после возврата обратно на фрагмент приходится заново данные перезагружать ибо иначе будет висеть старый Стейт - прогресс. А вроде как не хочется. Не понимаю пока как правильно обработать такой Кейс.
Если данные из локалки, то в целом не вижу ничего страшного, но конкретно на этот случай, можно не использовать sealed class и хранить все в одном data class, а там соответственно будет поле с данными и поле isProgress, тогда достаточно будет только флаг сбросить
12:10 почему не sealed interface? Они же легче вроде, я их обычно использую
Их тогда не существовало, а еще у них есть проблема с интеропом в иос (но это если про кмм говорить)
@@MobileDeveloper не знал что они так недавно появились
Почему бы не использовать State из композа вместо LiveData? Есть какие-то существенные причины так не делать или это просто для примера?
Например то, что для использования State тебе нужно чтоб все твои функции были Composable
Спасибо за видос, как всегда довольно понятно.
Я один вижу как мерцает экран при каждом переходе? Выглядит так, будто вначале отрисовывается белый пустой экран, а потом вызывается composable функция
Это не белый экран, это риппл эффект ) уберу его в ближайшем релизе)
Эх, жаль конечно нельзя посмотреть исходники из видео. Те что на гите отличаются и частично нет материала
Спасибо за видео! А можно ли подружить compose , navigation и dagger 2 вместо hilt? Есть реальные причины, почему я не могу юзать hilt ((
Да, вполне ) там придётся чуть кода ещё дописать, но можно
Не понимаю для чего в VM писать логику. На мой взгляд если её и использовать то только проксируя все вызовы до feature. А вообще пора выкидывать её)
Тут сразу по нескольким причинам. 1 - к этому привыкли люди и у многих проекты выстроены на вьюмодели и моя задача была показать, что можно оставаться на ней, используя компоуз. 2 - В целом, если проект небольшой, то какая разница как ты это назовешь VM или Interactor ) смысл от этого не сильно поменяется ) А где-то это все объединять нужно, потому что так проще работать командой
у вас есть обучение?
Да есть, очное и онлайн)
@@MobileDeveloper а как найти? как ваш сайт называется?
@@ТатьянаТ-е2л напишите мне в телеграм пожалуйста @neuradev
"Рожание" нового стейта убивает весь смысл компоуза (который состоит в том, чтобы рекомпозировать только те части, на которые повлияли конкретные переменные вью-модели). Тут же получается, что при любом чихе будет рекомпозироваться ВСЁ
А что мешает логически разбить экран на несколько функций, которые будут принимать в качестве аргумента несколько полей из стейта?
Нет, не будет) можете проверить. Рекомпозируется только то, что изменилось реально. Только что логами прошелся
Так и не отрефакторил? А то в репе ничего нового
Спасибо!
Спасибо, что поддерживаете канал! ))