Comments 44
Мне кажется, что я использую связку React+Redux вполне стандартным образом. Просто я ввел некоторые ограничения, которые гарантируют, что все плюсы, которые дает нам Redux не будут сведены на нет. Про возможное убийство плюсов я писал.
Насчет "если нет возможности использовать Flux то зачем использовать редукс" не могу согласиться. Redux — всё-таки это не Flux (про отличия от предшественников можно почитать тут https://github.com/reactjs/redux/blob/master/docs/introduction/PriorArt.md )
Зачем строить MVC? Потому что плюсов масса, и потому что это легко сделать — посмотрите код всего приложения, там никаких кастомных решений нет — всё беру из коробки.
Вы говорите, что модели здесь вообще нет.
Описание модели из русской википедии:
Модель (англ. Model):
Предоставляет знания: данные и методы работы с этими данными;
Реагирует на запросы, изменяя своё состояние;
Не содержит информации, как эти знания можно визуализировать;
Экземпляр Store из Redux:
Предоставляет знания: данные и методы работы с этими данными — YES
Реагирует на запросы, изменяя своё состояние — YES
Не содержит информации, как эти знания можно визуализировать — YES
Не вижу противоречий.
Controller связывавает View и Model. Здесь всё стандартно
Дело в том, что React-компонент может выполнять все роли из MVC — хранить данные, обрабытывать их и рулить другими компонентами, может даже дергать функции дочерних компонентов через Refs. Из-за таких широких возможностей многие лепят архитектуру как попало. Я же предлагаю вариант наведения в коде порядка, спроецировав старые добрые принципы в новую реальность
Дело в том, что React-компонент может выполнять все роли из MVCВот поэтому тут не стоит даже упоминать MVC, чтобы избежать любой путаницы.
Если лезть в детали — Store не меняет свое состояние сам, и не содержит сам по себе никаких методов работы с этими данными. Более того, там могут храниться как данные приложения (domain data), так и различные аспекты состояния UI. Redux — это «state container», а не модель. И не пытается быть последней. Редьюсеры меняют любое состояние, и отнюдь не обязательно связанное с бизнес-логикой приложения. С очень большой натяжкой можно назвать всю эту часть «моделью», и то только для тех, кто вот без MVC вообще не может понять что за что отвечает. Но, как по мне, это изначально неверный способ думать об архитектуре Redux-приложений.
Если лезть в детали — Store не меняет свое состояние сам, и не содержит сам по себе никаких методов работы с этими данными
Если уж совсем грубо, то это ужасная «тонкая модель» из мира MVC (не академического, а того, который часто реализуют на практике). А компоненты на реакте — вьюшка и толстый контроллер.
Я понимаю, что хочется казаться модным и утверждать, что здесь нет ничего из поганого мира ооп, но то, что вы старательно даете старым вещам новые имена не делает эти вещи новыми.
Да не, модным никто и не пытается казаться, и кто-то говорил что-то про «поганый мир ООП» (я так не считаю)? Я только о том, что не нужно все под одну гребенку MVC, потому что так вроде бы проще. Элементов больше, стыки между M, V и C без натяжки не сделать, да и незачем.
Насчет middlewares: я использую redux-thunk. Без проблем прикрутится redux-devtools, какой-нибудь логгер и т.д… По-идее middlewares не должны мешать
Пример использования redux-thunk:
function submit() {
return function(dispatch, getState) {
const state = getState();
dispatch(reset());
request('/auth/', {send: {
login : state.login,
password : state.password
}}).then(function() {
router.push('/');
}).catch(function() {
window.alert("Auth failed")
});
}
}
То что подход многими реализуется через одно место, вовсе не означает, что это подразумевается подходом.
разделение данных и представления
Очень грубое упрощение. MVC про разделение бизнес-логики (с данными) и логики представления (может быть тоже со своими данными).
Тогда MVVM — тоже MVC? Document-Model — тоже MVC?
Redux — это не совсем MVC, но выполняет ту же функцию: разделяет данные, представления и изменения данных.
Про "легко" и "MVC" я написал, потому что для реализации его принципов в связке React и Redux не нужно никаких надстроек, не нужно своего кастомного кода — нужно лишь придерживаться пары простых принципов, как раз для хорошей организации кода
Ну справедливости ради глобальное состояние не подразумевает отсутствие декомпозиции.
Каждая часть состояния может управляться независимыми редьюсерами.
В случае календаря его внутреннее состояние — это открыт datepicker или закрыт, текущий выбранный месяц и год, режим показа (некоторые календари позволяют переходить в режим выбора месяца или года по клику по дате). Для такого компонента состояние — это нормально, и не нужно выносить его в application state. В то же время список дат из рабочего графика — это состояние внешнее по отношению к компоненту, это application state и его нужно хранить и обрабатывать редьюсерами.
При использовании Stateful-компонентов, чтобы достать их State, придется использовать Refs.
вы хотите зачем-то знать state дочерних компонентов? зачем использовать refs для того, чтобы читать this.state?
Ставить рамки это хорошо. Чем жестче ограничения, тем однообразнее будет код.
Да — я думаю, что state внутри компонента это плохая идея, и стоит избегать его использования. Единственный случай, когда это правда необходимо — это разработка компонента, который может работать в обоих, в Stateful и Stateless, режимах. Классический пример это React-овский Input. Он умеет Controlled/Uncontrolled режимы. И ведет себя сильно по-разному.
tryAutoFill ничем не отличается от updateLogin. Т.е. Компонент знает, что какие-то callback-и будут, знает интерфейс, но не имеет представления о реализации
- "Умные" компоненты появляются только, когда лень реализовывать правильно.
Не стоит загаживать хранилище такими вещами, иначе потом там сам черт ногу сломит.
Неужели вы ни разу не упирались в то, что с каким-то Stateful-компонентом со временным State не удается реализовать нужный сценарий, и приходится много переписывать?
Вас Undo/Redo не беспокоит? Или серверный рендеринг?
Проблемы не надуманы — они реально существуют
TODO-App. Там не все идеально, но вот большой пример с тем же подходом https://github.com/MrCheater/react-spa-todo
Честный MVC на React + Redux