Реактивное программирование — парадигма программирования, ориентированная на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных, а также то, что нижележащая модель исполнения должна автоматически распространять изменения благодаря потоку данных.
Не для спора, но в Реакте (да и везде) это есть — это поток данных из родителя в потомков через свойства. Тут, конечно, можно придраться к слову "автоматически" — Реакт распространяет изменения автоматически, но явным образом — через задание свойств каждого элемента. От неявного распространения — передачи данных через контекст — много проблем, поэтому от него почти все фреймворки уходят.
Послушайте, знает уже весь хабр про ваш mol. Честно говоря он ужасен и не уверен, что кто-то кроме вас его понимает и использует.
Он, похоже, весьма продвинут в плане внутренностей (и там даже есть вещи, которые нельзя реализовать в том же реакте), но синтаксис шаблонов ужасен. Нет, я уверен, что после изучения и подавления изначального впечатления, пользоваться им будет можно и, наверное, даже удобно. Но в том виде, котором он есть — не взлетит.
Одной строки, Карл! Какая вам разница асинхронное или синхронное значение выставляется? Разве не фреймверк должен заботиться о такой рутинной операции как разрешение промиса и запись в стейт? Сколько кода просто хломиться вот таким подходом.
А обработка ошибок? А индикатор загрузки? А перезагрузка?
Ради интереса: вы какие-нибудь фреймворки использовали в продакшн кроме Ext JS и UniGUI?
Реакт это каким образом слой абстракции над DOM? Оно же просто за шкирку берёт и мордой в свой псевдо-XML салат тыкает всю дорогу, причём ещё и в оторванный от HTML.
А что по-вашему тогда абстракция? А React Native тоже browser DOM использует? А серверный рендеринг?
Конечно, результат. Вы смотрите и видите, какая нода получилась. А потом, увидев ng-repeat, понимаете, что там не одна она такая, а их много. гляда на произвольный js-код в JSX вам надо в уме выполнить этот код, чтобы получить ту информацию, которая вслучае шаблонизатора есть сразу.
Ну так вы когда джаваскрипт код читаете, вы его в уме выполняете? С JSX все так же.
Ну так в SPA у вас тот же код, который раньше был серверным, теперь на клиенте.
С чего бы это серверному коду быть на клиенте? Да и каким образом это возможно, ПХП выполнялся на сервере, реакт и другие — на клиенте. Он при всем желании не полезет в базу, не прочтет файл с диска на сервере и т.п.
Легко догадаться, что так делать не надо.
Знаете, я был практически уверен, что вы скажете "зелен виноград".
Так делать не хочется, пока не попробуешь :) Но это же мощнейший инструмент, который позволяет кучу задач (особенно при разработке библиотек и компонентов) решить изящным способом.
По сути, это и есть полноценная композиция компонентов, а не огрызок, как в Ангуляре.
Во втором ангуляре шаблоны компилируются в js-объект, точно так же, как jsx.
Совсем не так же. В Реакте можно оперировать результатами там же, в коде, то есть это по сути другой вид записи. В Ангуляре результат компиляции коду компонента не доступен.
Но вот только в ПХП был серверный код бизнес-логики вперемешку с HTML.
Дело не в JSX, конечно же. Есть несколько альтернатив ему, в том числе, и весьма похожие на шаблонизатор Ангуляра, которые позволяют писать как бы HTML, и компилировать его в вызовы createElement.
Но их никто не использует. Потому что настоящая мощь Реакта — в том факте, что компоненты — это обычные JS объекты. Я не устаю писать это в каждом комментарии в сраче о JSX.
Шаблон Ангуляра — это, конечно, похоже на ХТМЛ (особенно, если ты видел пример из getting started и не видел реальный production код). Но это все-равно строка.
И если нужно взять все вложенные компоненты, и оставить только часть из них по условию — то начинаются костыли. Но для этого хотя бы есть средства.
А вот как взять потомков одного типа, и склонировать их для каждого элемента массива и отрендерить в отдельное место? Или обернуть их в другой компонент? В реакте это делается элементарно. В языках с шаблонизаторами это либо вообще нельзя сделать (как в ангуляре 1), либо делается через ковыряние в потрохах (как во Вью).
Редакс прекрасно типизируется. С type-guards типизируются редьюсеры. connect вообще-то типизированный, но с отвратительными тайпингами, которые не используют новые фишки Typescript вроде mapped types.
Это исчезает из многих роутеров, например, из последнего react-router.
Для этого есть причина, как я понял, — это поддержка сложных динамических урлов, нефиксированной вложенности и прочих редких случаев. По сути, отдельной страницы для урла может и не быть, будет лишь динамический набор компонентов.
Однако, отсутствие opt-out статического именованного роутинга реально напрягает, сейчас он нужен в 90% случаев.
Формы в редаксе — это головная боль, конечно. В основном сложности возникают, когда пытаешься перенести "подход ангуляра" с двусторонним байндингом, валидацией инпутов и прочим на реактивность и иммутабельность.
Для себя я многое переосмыслил в подходах к разработке форм с редаксом, когда понял, что ошибки валидации не нужно нигде хранить (кроме тех, конечно, которые пришли с сервера). Их нужно вычислять.
Я имел ввиду объект, который содержит методы типа ПолучитьВсехАктивныхПользователей, ОбновитьОнлайнСтатус, и т.п., которые отражают предметную область.
Спецификации — это (компонуемое) описание операций над набором данных, по сути + универсальный метод их исполнения.
Мне нравится репозиторий как набор запросов.
Только не один гигантский на весь проект, а набор маленьких по сущностям и фичам.
В чем преимущество
легко мокать (если они маленькие).
сразу видно какие именно операции с базой могут выполняться
При этом необязательно отказываться от всего описанного в статье: репозиторий вполне может возвращать IQueryable, и к нему можно применять спецификацию.
Обобщенный репозиторий плох тем, что он не ограничивает никак ни чтение данных (т.к. доступна вся таблица), ни запись.
Свой же репозиторий может в методе All() возвращать не всю таблицу, а только доступные пользователю записи, например.
Также репозиторий как набор запросов позволяет легко и безболезненно для остального кода проводить оптимизацию отдельных методов, перенося их в базу как функции или вьюшки.
Не для спора, но в Реакте (да и везде) это есть — это поток данных из родителя в потомков через свойства. Тут, конечно, можно придраться к слову "автоматически" — Реакт распространяет изменения автоматически, но явным образом — через задание свойств каждого элемента. От неявного распространения — передачи данных через контекст — много проблем, поэтому от него почти все фреймворки уходят.
Он, похоже, весьма продвинут в плане внутренностей (и там даже есть вещи, которые нельзя реализовать в том же реакте), но синтаксис шаблонов ужасен. Нет, я уверен, что после изучения и подавления изначального впечатления, пользоваться им будет можно и, наверное, даже удобно. Но в том виде, котором он есть — не взлетит.
А обработка ошибок? А индикатор загрузки? А перезагрузка?
И именно этим он хорош!
Ради интереса: вы какие-нибудь фреймворки использовали в продакшн кроме Ext JS и UniGUI?
А что по-вашему тогда абстракция? А React Native тоже browser DOM использует? А серверный рендеринг?
Ну да, Реакт — он для программистов. Впрочем, утверждение, что шаблоны Ангуляра будет делать верстальщик — это, скажем так, самообман.
А изменение коллекции
@ContentChildrenкак-то повлияет на содержимое компонента?Ну так вы когда джаваскрипт код читаете, вы его в уме выполняете? С JSX все так же.
Более того, map — это джаваскрипт, npRepeat — это микроязык, свой для каждой директивы.
С чего бы это серверному коду быть на клиенте? Да и каким образом это возможно, ПХП выполнялся на сервере, реакт и другие — на клиенте. Он при всем желании не полезет в базу, не прочтет файл с диска на сервере и т.п.
Знаете, я был практически уверен, что вы скажете "зелен виноград".
Так делать не хочется, пока не попробуешь :) Но это же мощнейший инструмент, который позволяет кучу задач (особенно при разработке библиотек и компонентов) решить изящным способом.
По сути, это и есть полноценная композиция компонентов, а не огрызок, как в Ангуляре.
Совсем не так же. В Реакте можно оперировать результатами там же, в коде, то есть это по сути другой вид записи. В Ангуляре результат компиляции коду компонента не доступен.
Но вот только в ПХП был серверный код бизнес-логики вперемешку с HTML.
Дело не в JSX, конечно же. Есть несколько альтернатив ему, в том числе, и весьма похожие на шаблонизатор Ангуляра, которые позволяют писать как бы HTML, и компилировать его в вызовы
createElement.Но их никто не использует. Потому что настоящая мощь Реакта — в том факте, что компоненты — это обычные JS объекты. Я не устаю писать это в каждом комментарии в сраче о JSX.
Шаблон Ангуляра — это, конечно, похоже на ХТМЛ (особенно, если ты видел пример из getting started и не видел реальный production код). Но это все-равно строка.
И если нужно взять все вложенные компоненты, и оставить только часть из них по условию — то начинаются костыли. Но для этого хотя бы есть средства.
А вот как взять потомков одного типа, и склонировать их для каждого элемента массива и отрендерить в отдельное место? Или обернуть их в другой компонент? В реакте это делается элементарно. В языках с шаблонизаторами это либо вообще нельзя сделать (как в ангуляре 1), либо делается через ковыряние в потрохах (как во Вью).
То же самое, первый Ангуляр любил до Реакта. Второй, правда, попробовал еще до Реакта и невзлюбил сразу.
Ну и опять же, недавно добавили неявный вывод типа, возвращаемого из функции, что могло бы помочь сделать человеческие тайпинги для коннекта.
Редакс прекрасно типизируется. С type-guards типизируются редьюсеры.
connectвообще-то типизированный, но с отвратительными тайпингами, которые не используют новые фишки Typescript вроде mapped types.Это исчезает из многих роутеров, например, из последнего react-router.
Для этого есть причина, как я понял, — это поддержка сложных динамических урлов, нефиксированной вложенности и прочих редких случаев. По сути, отдельной страницы для урла может и не быть, будет лишь динамический набор компонентов.
Однако, отсутствие opt-out статического именованного роутинга реально напрягает, сейчас он нужен в 90% случаев.
Формы в редаксе — это головная боль, конечно. В основном сложности возникают, когда пытаешься перенести "подход ангуляра" с двусторонним байндингом, валидацией инпутов и прочим на реактивность и иммутабельность.
Для себя я многое переосмыслил в подходах к разработке форм с редаксом, когда понял, что ошибки валидации не нужно нигде хранить (кроме тех, конечно, которые пришли с сервера). Их нужно вычислять.
Есть и встроенный в TS Server auto-import
Я имел ввиду объект, который содержит методы типа ПолучитьВсехАктивныхПользователей, ОбновитьОнлайнСтатус, и т.п., которые отражают предметную область.
Спецификации — это (компонуемое) описание операций над набором данных, по сути + универсальный метод их исполнения.
Ок, спасибо за поправку. Я употребил "репозиторий" в смысле объекта для доступа к данным в хранилище.
Мне нравится репозиторий как набор запросов.
Только не один гигантский на весь проект, а набор маленьких по сущностям и фичам.
В чем преимущество
При этом необязательно отказываться от всего описанного в статье: репозиторий вполне может возвращать IQueryable, и к нему можно применять спецификацию.
Обобщенный репозиторий плох тем, что он не ограничивает никак ни чтение данных (т.к. доступна вся таблица), ни запись.
Свой же репозиторий может в методе All() возвращать не всю таблицу, а только доступные пользователю записи, например.
Также репозиторий как набор запросов позволяет легко и безболезненно для остального кода проводить оптимизацию отдельных методов, перенося их в базу как функции или вьюшки.