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

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

Думаю стоит добавить в цикл статей их свежеопубликованный подход к разработке на React — Flux.
Насчет Flux я планировал рассказать. Пока что у меня не оформилась четкая картина о том, как должна строится на нем архитектура и каков он в поддержке. Но идея интересная.
Под react многое можно подложить в плане того как управлять состоянием. И мне кажется что вот этот flux — он для приложений типа фейсбука хорош, а для многих других — нет. Фейсбук же слеплен из кучи более-менее независимых виджетов, которые вероятно пилят разные команды. И которые в разных комбинациях появляются на страницах. И им важно с этой темой не свихнуться. Поэтому у них несколько разных состояний, и flux этот разруливает чтобы они как-то более-менее синхронно жили. Короче flux наверное хорош для приложений из отдельных виджетов, которые активно меняют состояния и активно взаимодействуют.

У меня вот в опердени — гриды и формы. Там проще и понятнее держать весь стейт одним куском — и никакой синхронизации не нужно. Зато нужно редактировать поля стейта в глубине иерархии. Поэтому я приделал что-то типа линз — штуки, которая тащит с собой value, requestChange, isValid, performAction(state) и еще кучу всякого. И от которой можно рекурсивно отколоть кусочек с таким же интерфейсом — для вложенных в стейт объектов и полей, и отдать компоненту ниже. А сверху иерархии — штука, которая управляет всем стейтом, и умеет save/load/revert changes/performServerAction и т.п. Как по мне — для такого типа приложений неплохо работает.

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

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

Плохо что хороших, годных библиотек про это пока нет, но думаю что они не заставят себя долго ждать.
Мы недавно зарелизили библиотеку React Forms, которая работатет по описанному вами принципу:
github.com/prometheusresearch/react-forms
У нас был свой велосипед на эту тему. Постараюсь рассказать о нем в следующих статьях.
Да, очень похоже на то, что я на коленке себе нарисовал. Даже удивительно как мысли сходятся.

Правда я не так жестко привязался именно к формам — у меня несколько штуковин, не сильно даже к react приделанных.

У меня есть линза, которая похожа на вашу, но сразу тащит всё — и данные, и метаданные, и валидацию. Т.е. в стейте лежит:
formState = { name: «Ivan» }, validationState = { name: { isValid: true } }, metadata = { name: { isRequired: true } },
мы делаем var childLens = lens.prop('name'), и у нас будут childLens.value, childLens.validation.isValid, childLens.metadata.isRequired.

Линзу со стейтами я создаю на верхнем уровне, и растаскиваю по контролам вниз — просто делаю какую нужно подлинзу, и отдаю через props.

Есть обертка для контролов — почти как у вас, которая умеет рисовать label и validationError. Плюс набор всяких стандартных input-ов, и штука для массивов — тоже почти как у вас.

Есть обертка над данными формы — которая умеет всякое высокоуровневое — типа save и revert changes. Или, к примеру, saveAndPerformAction(fn) — если не сохранено, то спрашиваем надо ли сохранить, потом валидируем, если валидация проходит — сохраняем, и потом выполняем асинхронную fn, которая может вернуть новый стейт формы. Это нужно чтобы на сервере что-то сделать с редактируемой штукой.

В результате получается корневой контрол-обертка над формой с кнопками save, а внутри — иерархия компонент, которые редактируют куски стейта формы. Где-то обычными input-ами с валидацией, где-то — чем-то нестандартным под конкретную задачу.

Короче буду следить за вашим проектом, может как-то пересечемся еще.
| Все-таки ничто MVC-шное React не чуждо. M – state. V – вся функция render. С – корневой виджет.
Если так подходить, то любой шаблонизатор — это MVC-фреймворк, что не является верным. Как минимум в силу определения MVC.
К тому же, Facebook подошел исключительно верно к своему детищу. Они позиционируют ReactJS как View в вашем продукте, построенном по MVC. Т.е. вы не превращаете свою разработку в M(MVC)C, что в последнее время пропагандируется как «правильный подход» для построения dynamic clientside.
React является view-ориентированным MVC фреймворком

На мой взгляд такая формулировка будет точнее.
Что это значит? view-ориентированный?
MVC это парадигма и методология, которая рассказывает о разбиении сущностей на категории и опсывает способ их взаимосвязи.

Как минимум взаимодействие между двумя компонентами в ReactJS никак не укладывается в MVC. Соответственно и внутренняя работа ReactJS точно говорит о том, что эта библиотека ни коим образом не реализует паттерн MVC.

Привязывать распиаренный термин сюда не надо.
Если можно, раскройте, пожалуйста, подробнее термин MVC с тем смыслом, который вы в него вкладываете.
Я воспринимаю парадигму MVC как её задумывали авторы и описали очень жесткую методологию её реализации для Smalltalk-80
В документе описывается терминология, категории сущностей и их взаимодействие. А в конце приводятся примеры реализации на Smalltalk-80.

Всё что видел я в интернете, включая вики — это произвольная интерпретация MVC. Некоторые считают, что MVC для веба — это нечто другое, и подводят под него всё что имеет Модели, Шаблонизатор и какой то механизм их связи.

p.s.
www.itu.dk/courses/VOP/E2005/VOP2005E/8_mvc_krasner_and_pope.pdf
Ну на Smalltalk ссылка это не слишком убедительно. Кто-то знает, о чем вы говорите? Кто-то бросился гуглить MVC Smalltalk? Сомневаюсь. Напишите свои аргументы более внятно.
И вот ваша единственная ссылка:
image
Не обязательно знать Smalltalk, что бы понять MVC в том виде в котором он задумывался.
Я просил объяснить MVC так, как Вы его понимаете. Как я его понимаю:
1. M — уровень работы с данными, плюс вся бизнес-логика
2. V — рендеринг конечного результата на основе данных, которые были переданы во view
3. C — связующее звено между M и V, никакой бизнес-логики

Какая разница, в каком виде задумывался паттерн? Давайте еще про фортран разведем флейм. Важно то, что есть сейчас.
Это и называется что хочу то как MVC и интерпретирую.
Чем в вашем случае это отличается от MVP?
Да забейте уже. Очевидно же что под MVC понимают десяток разных конкретных конструкций. А если же лезть в абстракции — то модель, контроллер и представление можно найти в чем угодно. Класс, например: поля — модель, методы — контроллер, toString() — view :)
Если каждый человек будет придумывать свою трактовку, то от некоторых паттернов проектирования ничего не останется. Вы можете не привязываться к терминологии, если хотите, но не стоит говорить, что MVC можно трактовать по-разному. Трактовка всего одна
Спасибо за трактовку. Теперь можно разобрать ее и убедиться почему React теоретически может являться MVC-библиотекой. Да странное название, но тем не менее.

Выдержки из трактовки:
Model
The model has two jobs: it must both store a state and manage subscribers. The state does not need to be anything special; you simply need to define how you're going to store data, with setters and getters. However, anything which can change (any property) must have a list of listeners which it contacts whenever the value changes.

Что мы видем в React? У нас есть state где происходит store a state, плюс у нас есть методы lifecycle у View, такие как: componentDidUpdate, componentWillUpdate, которые manage subscribers. State просто store data, и мы можем выполнить get data через this.state и произвести set через setState. Каждое изменение state прослушивается и при необходимости выполняет componentDidUpdate. В данном случае listener только один сама View у которой находится state.

View раскрывать не буду и так все ясно.

Controller
the parts which do not update when the model changes — are the responsibility of the controller. This includes navigating around the view, as well as what you do when someone tries to edit the data in the view. Strictly speaking, a view cannot be edited and is 'read-only' — when you try to modify a field in the view, the controller needs to pick up the editing event, process it, and send it to the model; the model will then update the view if/when the value actually changes.

Что мы видим. Благодаря shouldComponentUpdate, мы можем обновлять или не обновлять визуальное представление View в браузере. Плюс у нас есть методы handler, которые navigating around the view, as well as what you do when someone tries to edit the data in the view. И те самые callback, которые есть почти у каждого виджета, через которые мы возвращаем данные в корневой виджет для изменения state.
А далее controller needs to pick up the editing event, process it, and send it to the model; the model will then update the view if/when the value actually changes. Какое совпадение слово в слово совпадает с тем, как реализованы изменения в React.
Вы перечисляете методы одного объекта и утверждаете что это MVC, где по определении всё разделено — суть парадигмы.
И что такое MVC-библиотека? Первый раз о таком слышу.
Может потому что у вас в голове винегрет из терминов, вы приплетаете MVC туда, где его нет?
MVC-библиотека — библиотека, которая которая реализует паттерн MVC. Определение паттерну было дано выше. В целом довольно бесполезный спор на самом деле, т.к. предмет разговора очень субъективен. Он не несет никакой как практической ценности, так и теоретической. Относительно винегрета в моей голове предлагаю продолжить в ЛС.
MVC-библиотекой

Вы ничего не путаете? MVC — шаблон проектирования. React может лишь реализовывать(или не реализовывать) этот архитектурный шаблон. И он не реализует его.

У нас есть state где происходит store a state

Да, мы сохраняем состояния, но не данные. Сохранение данных в состояниях является порочной практикой, я думаю вы должны знать об этом. Соответственно, данные которые должны сохраняться/изменяться в процессе работы с view, будут сохраняться не через React, верно?

Состояния работают по принципу модели, но это не даёт вам права говорить, что это реализация M из MVC.
А в корневом виджете у нас находятся данные или состояние? В нем на мой взгляд стирается грань между тем и другим. По сути состояния хранящиеся в корневом виджете представляют из себя срез данных в конкретный момент времени. Они являются состоянием для приложения, но данными для дочерних View.
В своей работе я рассматривал вариант отказаться от верхнего state и заменить его каким-нибудь хранилищем типа Cortex или Backbone.Model. В теории таким образом можно было бы избежать перерендеринга всех дочерних вьюх. Но теорию на практике не попробовал.
Есть замечательный метод shouldComponentUpdate, который решает проблему перерисовки дочерних представлений в зависимости от измененной информации. А по поводу Cortex или BB Model — это шаг в верном направлении, но на мой взгляд, раз уж React предполагает работу с immutable данными, то и механизм, который мы должны использовать в качестве модели хранилища, должен реализовывать возможность работы с таким типом данных. Из коробки ни Cortex, ни BB Model не умеют этого делать. Посмотрите в сторону flux, это дает пищу для размышлений
shouldComponentUpdate конечно решает. Но он увеличивает связанность кода от внешних props или state. В этом его главный минус, но для баг фиксинга и оптимизаций он отлично подходит.
Вообще говоря, создатели React сами его отделяют от MVC — посмотрите любую презентацию, хоть www.youtube.com/watch?v=IVvHPPcl2TM

Здесь вообще один из авторов сравнивает UI-архитектуры с архитектурами распределенных систем и говорит, что MVC — это аналог всяких архитектур типа SOAP, CORBA или RMI (которые не взлетели), в то время как React следует RESTful стилю.
Совсем не обязательно все притягивать всё за уши к MVC. MVC уже и так слишком много видов, чтобы понять что же это такое.
Позволю себе не согласиться с вами: React — это не фреймворк, это просто библиотека, которая предоставляет удобную и быструю работу с DOM, разделяя UI на виджеты. Я согласен, что это скорее похоже на View из стандартной MVC, но таковым не является, т.к. содержит в себе логику работы с данными.

Что касается статьи — очень достойно, было приятно прочитать.
Спасибо.
Соглашусь, пожалуй. На мой взгляд именно View во всем Web-стеке самое уязвимое место для изменения требований, т.к. его видят абсолютно все и поэтому изменения и недоработки сразу видны. Поэтому многие предпочитают не углубляться глубоко и рефакторят именно View слой не затрагивая остальные.

Идеология React для меня это по возможности stateless-компоненты, которые предсказуемы и их поведение ожидаемо. Плюс тесная интеграция с внутренним состоянием всего приложения через state корневого виджета позволяет буквально сериализовывать все состояние приложения в одну команду. Естественно тут большую роль начинают играть алгоритмы для копирования данных state, т.к. надо работать с immutable данными.
Да, я не по наслышке знаком с этим вопросом(я говорю о работе с данными). В данный момент я пишу небольшую библиотеку, которая будет предоставлять уровень абстракции для работы с immutable данными. Те же состояния, стек изменений и т.п. — только для данных. Я буду рад поделиться наработками и обязательно напишу об этом, но всему своё время. Думаю, это будет целая тема для разговора, т.к. имхо, сейчас работа с данными при использовании React — это самая слабая сторона.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации