Есть ли место для ООП в редуксе?

Я использую методы объектно-ориентированного программирования в течение 25 лет и пытаюсь перейти к функциональному программированию в течение последних 5 лет, но мой ум всегда идет к ООП, когда я пытаюсь сделать что-то сложное, и особенно сейчас ES6 поддерживает достойный синтаксис ООП, который естественным образом позволяет мне создавать материал.

Теперь я изучаю Redux, и я понимаю (cf Как поместить методы на объекты в состоянии Redux?), что это не-no для размещения экземпляров класса в ваших редукторах; и рекомендуемый способ вычисления поверх состояния простой редукции - с помощью селекторов (например, путем повторного выбора). И, конечно же, React рекомендует состав над наследованием (https://facebook.github.io/react/docs/composition-vs-inheritance.html, Реагировать на классы сокращения).

Но есть ли место в экосистеме React/Redux для объектов класса с методами и наследованием?

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

Если бы я собирался использовать ООП, мне нужно было бы отбросить идею о том, чтобы мои экземпляры сохранялись и поддерживали состояние на какое-то время? Например, каждый раз, когда я хочу использовать его, я бы создавал его из хранилищ данных, использовал любые методы, которые я хочу, и выбросил их? Это может устранить большой импульс для использования классов ООП. Но если я буду хранить примеры, у меня будут головные боли, которые будут синхронизироваться с магазином.

Итак, ответ на то, что всегда используйте селекторы, когда я соблазняюсь использовать методы и всегда использую композицию, когда у меня возникает соблазн использовать наследование? В частности, я имею в виду при хранении и управлении данными, хранящимися в хранилище Redux, для использования в компонентах React. И если да, то где он должен вписаться? Подключен к селекторам? Немедленно одноразовое, как я предложил?


Добавление моего прецедента для ясности: мои данные в основном представляют собой огромный график: множество объектов с большим количеством свойств и множеством взаимосвязей между объектами. Он читается только, но сложный. Мои объекты называются "понятиями".

Прежде чем сделать (возможно, глупое) решение перейти на Redux, я использовал классы для структурирования и представления концепций, наборов понятий и отношений между понятиями. Мои классы включали логику асинхронного api для извлечения наборов концепций, информации о каждой концепции и информации о других концепциях, с которыми связана каждая концепция. Если пользователь решил развернуть, классы будут рекурсивно извлекать и создавать экземпляры новых наборов концепций. В документации Redux рекомендуются плоские, нормализованные структуры для вложенных данных (http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html), что, вероятно, разумно для хранения, но моя модель ООП была хороша для прохождения разделы графика и прочее. Мне тяжело обворачивать голову с помощью селекторов и неизменяемого состояния, которые могут включать вложение, потенциально с циклами, или необходимость делать асинхронные вызовы для большего количества данных.

Я успешно использую https://redux-observable.js.org/ для файлов api.

Возможно, ответ @Sulthan прав: я должен свободно использовать методы ООП в моем приложении Redux. Но это все еще кажется странным. Я не могу удержать свои объекты, потому что, если хранилище изменится (например, будет получено больше данных), мои объекты могут стать устаревшими. Если мои объекты вложены, но мой магазин нормализуется, я создам их (из селекторов), когда они мне понадобятся, и не заставляйте их...

Ответ 1

Я отвечу на свой вопрос, описав, что я делаю, несовершенный, как есть.

Во-первых, вместо обычного синтаксиса класса ES6 я начал использовать stampit, что является более уродливым, чем классы ES6, но многое более гибким.

В основном, однако, мои сложные объекты существуют в двух формах:

  • простые объекты JS для хранилища
  • класса (фактически штампованные) экземпляры для удобства и мощности использования методов экземпляра.

Я использую соглашение о размещении _underscore перед всеми ссылками на простые объекты. Мое "решение" по большому счету неудобно и плохо, но я думаю, что пытаться использовать селекторов для всего будет хуже. Если вам интересно, вот место в моем коде, где я "раздуваю" мои объекты обычного хранилища в экземпляры: https://github.com/Sigfried/vocab-pop/blob/localstorage/src/ducks/conceptSet.js#L292

UPDATE

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

Я, вероятно, должен был принять ответ @markerikson, и, возможно, вещь Redux-ORM стоит посмотреть, но я просто хотел сказать окончательно, НЕ ДЕЛАЙТЕ, ЧТО Я ДЕЛ. (Я всегда думаю, что я настолько умный, используя заполнение "пробелов" технологий, которые я изучаю с помощью умных хаков, - и затем я трачу мучительные месяцы, очищая беспорядок, когда я понимаю, почему эта технология не включает мой взлом в первое место.)

Ответ 2

Ответ заключается в том, что он возможен, но сильно обескуражен и не идиоматичен.

React полагается на классы и одноуровневое наследование React.Component для реализации компонентов с состоянием с жизненными циклами, но вам официально не рекомендуется выполнять дополнительные уровни наследования в компонентах.

Redux построен на принципах функционального программирования. По целому ряду причин вам рекомендуется поддерживать ваше состояние как простые объекты и массивы JS, а также обращаться к нему/манипулировать с помощью простых функций.

Я, конечно, видел много библиотек, которые пытались добавить OOP-слой поверх Redux (например, классы, методы которых превращаются в создателей действий и редукторы). Эти работы, но определенно идут вразрез с общим духом Redux.

Я действительно использую библиотеку под названием Redux-ORM, которая позволяет вам определять классы моделей, которые действуют как фасад над равниной JS в вашем магазине. Однако, в отличие от многих других библиотек, которые я видел, он работает с Redux, а не пытается изменить поведение Redux. Я обсуждал, как работает Redux-ORM, как я его использую и почему он по-прежнему достаточно идиоматичен, в моих сообщениях в блоге Практический Redux, часть 1: Основы Redux-ORM и Практический Redux, часть 2: Концепции и методы Redux-ORM. В целом, это отличный инструмент для управления отношениями и нормализованными данными в вашем магазине Redux.

Наконец, я сейчас работаю над сообщением в блоге, в котором будут обсуждаться фактические технические ограничения, требуемые Redux (и почему), а также то, как вы планируете использовать Redux, и как можно использовать Redux. Надеюсь, что на следующей неделе или около того - следите за http://blog.isquaredsoftware.com.

Ответ 3

Этот вопрос немного основан на мнениях, но пусть сосредоточится на основных моментах.

Нет никакого противоречия между функциональным программированием и ООП. Вам просто нужно использовать одни и те же шаблоны программирования. Нет никакой проблемы использовать классы (с наследованием) в функциональном программировании, если вы держите их неизменными.

Чтобы доказать свою точку зрения, популярная библиотека Immutable.js, которая используется многими людьми для сохранения состояния в redux, состоит из классов. И эти классы имеют наследование (например, OrderedSet extends Set).

Также обратите внимание, что большинство компонентов React являются классами, и они также используют наследование (... extends React.Component).