Как стать автором
Обновить

Комментарии 38

Устоявшийся перевод термина actor - актор, а не актёр. Прям глаза режет.

Спасибо, исправил

:D:D Вот это дичь, все «советы» и «утверждения» прям из гайда от том, как делать НЕ НАДО.

Что именно вас смущает?

То, что вы как разработчик странно себе ведете и даже не попробовали в 2021 MobX на боевом проекте, хотя все уважающие себя разрабы с 2016 года начали на него переходить. Использовать Redux или голый React в наши дни это нелепость. Ещё большая нелепость писать об этом статьи, вы ещё про jQuery напишите сейчас)

Я бы не был таким категоричным. На MobX перешли те, чьи взгляды совпали со взглядами создателей MobX.
Я сознательно выбрал redux, так как для меня самым приоритетным условием есть хранение состояния в одном месте. На втором месте - простой просмотр и анализ этого состояния.

Если это единственная претензия к статье, тогда норм. Я думал, что что-то не так с моими знаниями в области редакса.
Добавлю в заголовок слово "редакс", чтобы небыло намека в агитации перехода на редакс.

Я сознательно выбрал redux,

Сознательный выбрал страдать) ради чего?

для меня самым приоритетным условием есть хранение состояния в одном месте.

Смысл?

простой просмотр и анализ этого состояния

А в MobX'e это сложно что ли?)
import { toJS } from 'mobx';
console.log(toJS(userState));

Извините, но вы как-то неадекватно общаетесь.

Вроде и есть что вам ответить, но я почитал ваш троллинг в других статьях, и у меня пропало желание тратить время на общение с человеком, который всех во круг себя считает идиотами.

Ну скажем так, говорить что выбор redux'a в 2021 году — осознанный выбор мягко говоря странно.
Отсюда и вопросы и насмешки.
В 2014-2015 годах я ещё могу понять из-за того что все было на зачаточной стадии и пока не успел народ освоиться в экосистеме реакта, с чем и как его лучше использовать, но сейчас это диковато.
Вся проблема в том, что вы после себя оставляете такое наследие из redux'овской лапши, которое не поддается дальнейшему развитию и поддержки, а остальным, которые приходят на проект после вас приходится с этим что-то делать, например переписывать с нуля.
Но за возможность переписать проекты с нуля искренние спасибо, это мой конек)
НЛО прилетело и опубликовало эту надпись здесь
я бы сказал так — категорично заявлять о то что выбор redux странен в 21м году — очень странно!

Нет, наоборот Redux в 21 году нелепо и смешно использовать.
думаю начинающих он раздражает в силу не способности его понять и осилить — это проблемы начинающих.

Нет, он раздражает всех потому что он заставляет и поощеряет писать отвратительный код. Спору нет, что мазахистам это наоборот нравится.
то к чему вы бегите с мобх предыдущие поколения проходили на Backbone — это старые грабли и от них бежали в redux — изучите историю и уроки

Нет, никаких граблей нет, все шикарно наоборот. И не путайте с Backbone с React+MobX это мягко говоря вообще небо и земля.

redux в 21м году по-прежнему занимает лидирующее положение в разработке крупнейших компаний из-за свой простоты, надежности и предсказуемости, а так же не высокому порогу входа.

Не, из-за тонн легаси начатых на нем и из-за того, что большинство не смотрит по сторонам, им и так сойдет, главно чтобы ЗП платили.

Задачи решаются не на скорость и то что вы считаете избыточностью в redux на практике не имеет никакого значения — важна прозрачность, предсказуемость и надежность как у молотка

Жаль что к реальности это не имеет отношения. В реальности огромная лапша, жуткий и нечитаемый говнокод из-за иммутабильности и принципа работы, невозможность дальнейшей поддержки/развития если кто-то увольняется.
НЛО прилетело и опубликовало эту надпись здесь
предложу вам статью на подумать без эмоций
www.robinwieruch.de/redux-mobx

И? Ничего нового. В чем ваш посыл от этой статью? Якобы что у redux'a есть хоть 1 плюс по сравнению с mobx чтоли? Redux как был ущербным инструментов так и остался, виной тому функциональщина и иммутабильность. Любой инструмент или подход следующий этим 2ум вещам ущербен и обречен.
обычно раздражение возникает у людей когда они не достаточно понимают что-то или не разобрались до конца в чем-то или из-за не большого опыта — не с чем сравнивать

Увы, не мой случай. У меня опыта полно и есть много с чем сравнивать, поэтому разумеется как и любой другой уважающий себя фронтендер который использует реакт, берет в связку только mobx, не ущербный mobx-state-tree, а именно просто mobx.
НЛО прилетело и опубликовало эту надпись здесь
можно почитать взвешенное давнее обсуждение плюсов и минусов обоих стейт-менеджеров

и тут ссылки на обсуждения и статьи

А своя голова есть на плечах? У меня вот есть, в статьях может быть написано все что угодно, главное это то, что мы имеем в реальности, а это далеко не всегда соответствует тому, что пишут в статьях.
Я 2 года писал на react + redux и 5 лет на react + mobx. Так что если вы сами не можете совершенно точно и четко указать на недостатки MobX по сравнению с Redux, причем опять же не чьи-то выдумки прочитанные в какой-то очередной статье, а реальные.
А так вы типичный «я делаю так и считаю так, потому что Вася Пупкин так сказал или потому что я прочитал это в статье» не имеющий своего личного мнения, а зависите лишь от мнения «авторитетов», как вам скажут те, кого вы считаете «авторитетами», так и будете думать.

хотел бы сделать 2 возражения

— глупо обвинять javaScript в функциональщине — вообще-то это фукциональный язык и попытка имитировать на нем ООП приводит к оверхеду на инициализацию инстансов и property lookup через цепочки prototypes

Я констатирую факт, ФП + иммутабильность + чистые функции = полнейший трэш и Write-only код. По поводу оверхэда, он настолько ничтожный что им можно приберечь, он повышает удобство, читаемость и т.п. на порядки раз, поэтому оверхэд на этом фоне ничтожество.

— иммутабельность вас раздражает — ее требует от нас сам React!

Нет, от слова совсем, если мы используем MobX.
НЛО прилетело и опубликовало эту надпись здесь
Посмотрите redux-observable, там уже реализовано подобный функционал.

Посмотрел. Идея статьи в том чтобы не увеличивать базу знаний проекта. Зачем мне добавлять еще одну библиотеку, если для этого достаточно реакта с хуками?

Если вы вводите новое понятие (актор) поверх существующих хуков, то по сути увеличиваете базу знаний проекта. То есть уже есть не только реакт с хуками, а ещё некоторая теория и соглашения.

Переименование "компонент" на "актор" не идет в сравнение с добавлением новой библиотеки. Единственное соглашение - это не использовать jsx (то есть ничего не рендерить), а остальная теория и соглашения должны быть уже знакомы.

А что в вашем понятии представляет из себя библиотека?

Да, неочень я выразился. Я имел ввиду библиотеки, которые вносят дополнительный опыт использования, который можно избежать используя уже подключенные библиотеки.

но создание npm модуля react-ghost и подключение этого модуля в проектах, тоже вносит дополнительный опыт использования,
чем в таком случае react-ghost принципиально отличается от других библиотек?

Тем что вносит значительно меньше дополнительного опыта

то есть npm модуль react-ghost это тоже библиотека просто с меньшим дополнительным опытом?

да

Тут все просто. Синхронную логику мы заносим в Redux, асинхронную — в Thunk.

Уж если мы всё делим на слои, то логично, что всю бизнес-логику (и синхронную, и асинхронную) мы выносим в Thunk (или Saga), а в Redux оставляем только состояние. Либо же я совсем не понял ваш посыл…

Посыл в том что вместо добавления +1 библиотеки (например thunk) достаточно использовать useEffect, который уже есть в реактею. Просто этот useEffect надо вызывать не в UI слое, а в отдельном слое бизнесс логики

PS: извените не заметил контекст вашего вопроса, и ответил не на то

логично, что всю бизнес-логику (и синхронную, и асинхронную) мы выносим в Thunk (или Saga), а в Redux оставляем только состояние

Имеется ввиду, что нет смысла прогонять простое действие через thunk, если его можно сразу обработать в редюсере. И эти простые действия в моем понимании - это тоже бизнесс логика

Всю бизнес логику выносить в thunk это плохая идея. Наоборот следует как можно больше логики держать в редьюсерах так как редьюсеры — это чистые функции. Я могу днями расписывать насколько хороши и предсказуемы чистые функции, но вы можете об этом и сами отдельно почитать. В 2-х словах их очень просто дебажить, тестировать, декомпозировать, композировать.


Так же редюсеры, это логика изменения состояния, в то время как thunk и другое, это по большей части логика общения с сервером. Отделив одно от другого логика изменения состояний лучше дебажится с помощью девтулзов и на много легче покрывается тестами.


Такой подход рекомендует сама документация redux, вот здесь:
https://redux.js.org/style-guide/style-guide#put-as-much-logic-as-possible-in-reducers

Мне кажется Вы создали хуки только назвали их акторы. Хуки они собственно и есть почти компоненты, в которых можно использовать внутри хуки, при этом они так же ничего не рендерят

Ну почти. Отличие лишь в том, что хук не может участвовать в условных операторах, а актор (как и компонент) - может. Кроме того актора можно обернуть в React.memo.

Но замечание хорошее. Бизнес логику можно описывать в хуках, но до тех пор, пока не надо делать сложную композицию с условными вложениями друг в друга.

На мой взгляд модель которая у вас получилась недотягивает до Actor model.
Вот например что XState пишет об Actor-ах:


"actor" that can do three things:
  • Receive messages
  • Send messages to other actors
  • Do something with the messages it received (its behavior), such as:
    — change its local state
    — send messages to other actors
    — spawn new actors

Википедия пишет примерно то же самое.
Давайте разберем пункты по порядку:


1) Может ли ваш Actor получать сообщения?
Нет, он может только реагировать на изменение состояния redux. Если сильно включить фантазию, то можно конечно считать это сообщением. Но строго говоря это не то.


2) Может ли ваш Actor отправлять сообщения другим Actor-ам?
Нет, он может только диспатчить в store. Это конечно в итоге может вызвать useEffect в другом Actor-е. Но если проходить к вопросу строго, то это все же не то.


3) Может ли Actor изменить свое внутреннее состояние?
Нет. Если рассматривать за внутреннее состояние состояние redux, то оно не внутреннее. Ну а если рассматривать локальное состояние компонента, то может конечно, только толку от такого локального состояния не много и статья как раз о работе с глобальным состоянием таким образом.


4) Может ли ваш Actor создать еще акторов?
Да. Он может рендерить их внутри себя, как у вас в примере.


Так же я не понимаю зачем строить эту отдельную иерархию акторов:


const AppActor = ({ param1, param2, showModalX }) => ghosts(
   ghost(MenuActor, { param1 }),
   ghost(PagesActor, { param2 }),
   showModalX && ghost(ModalXActor)
)

Почему нельзя просто отрендерить MenuActor в компоненте Menu, PagesActor (не уверен что это допустим что-то что нужно для всех страниц) в App и ModalXActor в компоненте ModalX? Получится почти то же самое, что держать useEffects прямо в компонентах или хуках, только без лишних рендеров. Я использовал такой подход.


И насчет "чем больше слоев тем лучше", это тоже не совсем так. Слои, конечно, помогают не превратить код в спагетти, однако если их больше чем нужно, то код легко превращается в лазанью :) Нужен баланс

На мой взгляд модель которая у вас получилась недотягивает до Actor model.

Я и не стремился реализовать именно эту модель (как минимум выдержать соответствие всем словам в определении).
Скорее наоборот, была идея и максимальным соответствующе слово, которое подошло — это Actor. Потому как, если, как вы заметили, включить фантазию на максимум, и «сообщение» приравнять к «информация» или «событие», то через общий стор можно и отправлять информацию и получать информацию/событие. А внутреннее состояние — не уверен что это вообще принципиально — useState я действительно не разу там не применил, но можно, например, контекст функции в useEffect считать внутренним состоянием.
Может показаться что я натянул сову на глобус, но это как раз тот случай когда сова хорошо на него налезла.

Вот, например, одна из статей, которая меня к этому подтолкнула:
Join The Dark Side Of The Flux: Responding to Actions with Actors

Там это так описывалось:
Actors are a sequence of functions which are called each time your store’s state change, with one important exception: they aren’t called in response to actions dispatched from other actors.
Акторы это последовательность функций, которые вызываются каждый раз когда изменяется состояние, с одним исключением — они не вызываются на действия задиспаченые другими акторами

Но в чем-то Вы тоже правы и может быть нужно другое название. Уже точно не помню, видимо поэтому год назад я назвал это «Призраком». Но мне показалось аудитории «Актор» будет более понятен.
Так же я не понимаю зачем строить эту отдельную иерархию акторов
Это, наверно, основная проблемма моей статьи — в том что я очень вскольз упамянул для чего это нужно и в каких ситуациях применяется. Думал это вынести в отдельную статью. Но попытаюсь объяснить тут.

Возьмем, например, ModalXActor — это призрак компонента ModalXComponent.

Причина 1. Разделили мы их потому что они будут состоять из разных блоков. Имеется ввиду не просто то что у актора будут блоки бизнесс логики, а у компонента будут блоки UI. Имеется ввиду, что они прям вообще не будут совпадать.
const ModalXActor = () => ghosts(
    // загрузка в state.Book.
    // Подписан на флаг "saving", по которому делает сохранение
   ghost(BookActor), 
   
   // загрузка истории изменений книги в state.ChangesHistory
   ghost(ChangesHistoryActor), 

   // загрузка коментариев и добавление новых в state.Comments
   ghost(CommentsActor), 
)

const ModalXComponent = () => <>
   // выводит заголовок книги из state.Book
   <Header>

   <TabMenu> // диспатчит в state.tabs текущий выбраный таб
   
   // выводит авторов книги из state.Book
   // + историю изменений из state.ChangesHistory
   {state.tabs.activetab === 'authors' && <TabBook>}

   // выводит первую страницу из state.Book
   // + историю изменений из state.ChangesHistory
   {state.tabs.activetab === 'firstpage' && <TabBookFirstPage>}

   <SaveButton> // диспатчит в state.Book флаг "saving = true" (см. BookActor)
</>

const TabBookFirstPage = () => <>
   <FirstPage> // выводит первую страницу из state.Book)
   <ChangesHistory> // выводит историю изменений из state.ChangesHistory
   <Comments> // выводит историю изменений из state.Comments
</>

Как видите смысл появляется когда у нас два визуально разных таба и каждому нужен доступ к одному и тому-же стейту. Или наоборот одна кнопка «Save», а отпраивть на сохранение надо два разных стейта.

Причина 2. Мы можем переключатся между акторами ModalXActor и ModalYActor в фоне, и только когда данные будут готовы — начать переключаться между ModalXComponent в ModalYComponent. Либо паралельно и независимо от акторов анимировать переключение UI.

Причина 3. Мы можем легко сделать мобильную версию сайта. Это Вам не выдумывать как хакнуть стилями видимость компонентов адаптивной версткой — достаточно просто поменять компоненты в UI слое. Все что компоненты будут делать — это брать состояние со стора и диспатчить екшены. Логику переписывать не надо, т.к. скорее всего набор действий не будет отличатся и если и будет то только в меньшую сторону.
Может даже получится оставить бизнесс логику без изменений, а UI подставить для React Native.

А вы не пробовали разобраться полноценно в client-side архитектурах? Читая такие статьи понимаешь, почему другие client-side программисты(mobile,desktop) фронтендеров всерьёз не воспринимают. Разберитесь с MVVM и Clean Architecture и будет вам озарение и счастье) Будут слои и приложения любой сложности будут разрабатываться на изи)
MVVM с MobX или RxJS вообще божественно заходят.

MVC и MVVM - первое что я попробовал когда ещё был студентом. Clean Architecture - тоже ещё один из вариантов набора слоев. Вы хотите сказать что я должен следовать именно этим подходам и не пытаться шагнуть в сторону?

Подозреваю, что мы вкладываем разный смысл в слово "слои", но хотелось бы все-таки больше конкретики, что вам не понравилось в статье?

А пока отвечу так:

А вы не пробовали разобраться полноценно в client-side архитектурах? Читая такие комментарии понимаешь, почему фронтендеры других client-side программистов(mobx) всерьёз не воспринимают. Разберитесь с FLUX, иммутабельностью, принципом единого источника истины, попробуйте однонаправленный поток данных и будет вам озарение и счастье) найдите например разницу ещё между css, jsx, js - будут слои и приложения любой сложности будут разрабатываться на изи)

FLUX с Redux или React hooks вообще божественно заходят.

FLUX с Redux или React hooks вообще божественно заходят.

Ахахах, дичь) Но не переживайте, это лишь до тех пор, пока вы джун) Потом наберетесь опыта, прозреете и все станет по другому.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории