Я из другого мира, где я мог бы извлечь логику в сервис / фабрику и использовать ее в своих контроллерах.
Я пытаюсь понять, как я могу добиться того же в приложении React.
Допустим, у меня есть компонент, который проверяет ввод пароля пользователя (это сила). Эта логика довольно сложна, поэтому я не хочу писать ее в компоненте, который она сама.
Где я должен написать эту логику? В магазине, если я использую флюс? Или есть лучший вариант?
reactjs
reactjs-flux
Деннис Неруш
источник
источник
Ответы:
Первый ответ не отражает текущую парадигму « Контейнер против презентатора» .
Если вам нужно что-то сделать, например, подтвердить пароль, скорее всего, у вас есть функция, которая это делает. Вы передадите эту функцию своему представлению для повторного использования в качестве опоры.
Контейнеры
Таким образом, правильный способ сделать это - написать ValidatorContainer, который будет иметь эту функцию в качестве свойства, и обернуть форму в него, передав правильные реквизиты дочернему элементу. Когда дело доходит до вашего представления, ваш контейнер валидатора оборачивает ваше представление, и представление использует логику контейнеров.
Валидация может быть выполнена в свойствах контейнера, но если вы используете сторонний валидатор или любой простой сервис валидации, вы можете использовать сервис как свойство компонента контейнера и использовать его в методах контейнера. Я сделал это для остальных компонентов, и это работает очень хорошо.
Провайдеры
Если требуется немного больше конфигурации, вы можете использовать модель поставщика / потребителя. Поставщик - это компонент высокого уровня, который оборачивается где-то рядом с верхним объектом приложения (тем, который вы монтируете) и передает часть себя или свойство, настроенное на верхнем уровне, в контекстный API. Затем я устанавливаю элементы контейнера для использования контекста.
Контекстные отношения родитель / потомок не должны быть рядом друг с другом, просто ребенок должен быть каким-то образом спущен. Таким образом, Redux хранит и работает React Router. Я использовал его для предоставления корневого контекста для моих контейнеров отдыха (если я не предоставляю свой собственный).
(примечание: контекстный API помечен как экспериментальный в документах, но я не думаю, что это больше, учитывая, что его использует).
Промежуточное
Еще один способ, который я не пробовал, но считал использованным, - это использование промежуточного программного обеспечения в сочетании с Redux. Вы определяете свой сервисный объект вне приложения или, по крайней мере, выше, чем хранилище с избыточностью. Во время создания магазина вы внедряете сервис в промежуточное ПО, а промежуточное ПО обрабатывает любые действия, которые влияют на сервис.
Таким образом, я мог бы внедрить свой объект restful.js в промежуточное ПО и заменить мои методы контейнера независимыми действиями. Мне по-прежнему нужен компонент контейнера для предоставления действий слою представления формы, но connect () и mapDispatchToProps меня там охватили.
Например, новый v4 реагирующий-маршрутизатор-редуктор использует этот метод для воздействия на состояние истории.
источник
Проблема становится чрезвычайно простой, когда вы понимаете, что служба Angular - это просто объект, который предоставляет набор независимых от контекста методов. Это просто механизм Angular DI, который делает его более сложным. DI полезен, поскольку он заботится о создании и поддержании экземпляров для вас, но он вам на самом деле не нужен.
Рассмотрим популярную библиотеку AJAX с именем axios (о которой вы, вероятно, слышали):
Разве это не ведет себя как услуга? Он предоставляет набор методов, отвечающих за определенную логику, и не зависит от основного кода.
В вашем примере речь шла о создании изолированного набора методов для проверки ваших входных данных (например, проверка надежности пароля). Некоторые предлагали поместить эти методы в компоненты, что для меня явно является анти-паттерном. Что если проверка включает в себя выполнение и обработку внутренних вызовов XHR или выполнение сложных вычислений? Вы бы смешали эту логику с обработчиками щелчков мыши и другими специфическими элементами пользовательского интерфейса? Ерунда. То же самое с подходом контейнер / HOC. Обернуть ваш компонент только для добавления метода, который проверит, есть ли в значении цифра? Давай.
Я бы просто создал новый файл с именем скажем «ValidationService.js» и организовал его следующим образом:
Тогда в вашем компоненте:
Используйте этот сервис из любой точки мира. Если правила проверки изменятся, вам нужно сосредоточиться только на файле ValidationService.js.
Вам может понадобиться более сложный сервис, который зависит от других сервисов. В этом случае ваш служебный файл может возвращать конструктор класса вместо статического объекта, так что вы можете самостоятельно создать экземпляр объекта в компоненте. Вы также можете рассмотреть возможность реализации простого синглтона, чтобы убедиться, что во всем приложении всегда используется только один экземпляр объекта службы.
источник
Мне нужна была некоторая логика форматирования для нескольких компонентов, и разработчик Angular также склонялся к сервису.
Я поделился логикой, поместив ее в отдельный файл
а затем импортировать его как модуль
источник
Имейте в виду, что цель React - лучше соединить вещи, которые логически должны быть связаны. Если вы разрабатываете сложный метод проверки пароля, где он должен быть связан?
Ну, вам придется использовать его каждый раз, когда пользователю нужно ввести новый пароль. Это может быть экран регистрации, экран «забытый пароль», экран «сброс пароля администратора для другого пользователя» и т. Д.
Но в любом из этих случаев он всегда будет привязан к некоторому полю ввода текста. Так вот, где это должно быть связано.
Создайте очень маленький компонент React, который состоит исключительно из поля ввода и соответствующей логики проверки. Введите этот компонент во всех формах, для которых может потребоваться ввод пароля.
По сути, это тот же результат, что и сервис / фабрика для логики, но вы подключаете его напрямую к входу. Так что теперь вам не нужно указывать этой функции, где искать входные данные для проверки, так как они постоянно связаны друг с другом.
источник
Я также пришел из области Angular.js, а сервисы и фабрики в React.js более простые.
Вы можете использовать простые функции или классы, стиль обратного вызова и событие Mobx, как я :)
Вот простой пример:
источник
Та же ситуация: после выполнения нескольких проектов Angular и перехода на React, не имея простого способа предоставления услуг через DI, это кажется отсутствующим элементом (не обращая внимания на особенности сервиса).
Используя контекст и ES7-декораторы, мы можем приблизиться:
https://jaysoo.ca/2015/06/09/react-contexts-and-dependency-injection/
Кажется, эти ребята сделали еще один шаг в другом направлении:
http://blog.wolksoftware.com/dependency-injection-in-react-powered-inversifyjs
Все еще хочется работать против зерна. Я вернусь к этому ответу через 6 месяцев после проведения крупного проекта React.
РЕДАКТИРОВАТЬ: Вернуться через 6 месяцев с еще немного опыта React. Рассмотрим природу логики:
Некоторые также достигают HOC для повторного использования, но для меня вышеупомянутое охватывает почти все варианты использования. Кроме того, рассмотрите возможность масштабирования управления состояниями с использованием уток, чтобы разделить проблемы и сосредоточить внимание на UI.
источник
Я тоже из Angular и пробую React, на данный момент, один рекомендуемый (?) Способ, кажется, использует компоненты высокого порядка :
Допустим, у вас есть
input
и вамtextarea
нравится применять одну и ту же логику проверки:Затем напишите HOC, который выполняет валидацию и стилизацию обернутого компонента:
Теперь эти HOC имеют одинаковое проверочное поведение:
Я создал простую демонстрацию .
Редактирование : другая демонстрация использует реквизиты для передачи массива функций, чтобы вы могли делиться логикой, состоящей из нескольких проверяющих функций, через
HOC
s, например:Edit2 : React 16.8+ предоставляет новую функцию, Hook , еще один хороший способ поделиться логикой.
https://stackblitz.com/edit/react-shared-validation-logic-using-hook?file=index.js
источник
HOC
, см. Мою правку для другой демонстрации.Сервис не ограничивается Angular, даже в Angular2 + ,
Сервис - это просто набор вспомогательных функций ...
И есть много способов их создания и повторного использования в приложении ...
1) они могут быть отдельными функциями, которые экспортируются из файла js, как показано ниже:
2) Мы также можем использовать метод фабрики, как, с набором функций ... с ES6 это может быть класс, а не конструктор функции:
В этом случае вам нужно сделать экземпляр с новым ключом ...
Также в этом случае у каждого экземпляра своя жизнь, поэтому будьте осторожны, если хотите поделиться им, в этом случае вы должны экспортировать только тот экземпляр, который хотите ...
3) Если ваша функция и утилиты не будут использоваться совместно, вы даже можете поместить их в компонент React, в данном случае, так же, как функцию в вашем компоненте реагирования ...
4) Другой способ, которым вы можете обрабатывать вещи, может быть использование Redux , это временное хранилище для вас, поэтому, если у вас есть это в вашем приложении React , оно может помочь вам со многими функциями установки сеттера вами ... Это похоже на большой магазин которые следят за вашими состояниями и могут делиться ими между вашими компонентами, чтобы избавить вас от многих неприятностей, связанных с установщиками-установщиками, которые мы используем в сервисах ...
Всегда полезно делать DRY-код, а не повторять то, что необходимо использовать, чтобы сделать код многократно используемым и читабельным, но не пытайтесь следовать угловым путям в приложении React , как упоминалось в пункте 4, использование Redux может снизить ваши потребности в сервисы, и вы ограничиваете их использование для некоторых повторно используемых вспомогательных функций, таких как пункт 1 ...
источник
Я в такой же загрузке, как ты. В случае, если вы упомянули, я бы реализовал компонент пользовательского интерфейса проверки ввода как компонент React.
Я согласен, что реализация самой логики валидации не должна (должна) быть связана. Поэтому я бы поместил его в отдельный модуль JS.
То есть для логики, которая не должна быть связана, используйте модуль / класс JS в отдельном файле и используйте require / import, чтобы отсоединить компонент от «службы».
Это позволяет вводить зависимости и тестировать модуль независимо друг от друга.
источник
или вы можете ввести наследование класса "http" в React Component
через объект опоры.
Обновить :
Просто отредактируйте React Component ReactApp следующим образом:
источник
Ну, наиболее часто используемый шаблон для логики многократного использования, с которым я сталкивался, это либо написание ловушки, либо создание файла утилит. Это зависит от того, чего вы хотите достичь.
Например, если вы хотите проверить данные формы, я бы создал пользовательский хук с именем useForm.js и предоставил бы ему данные формы, а взамен он вернул бы мне объект, содержащий две вещи:
Вы можете определенно вернуть больше вещей из этого по мере вашего прогресса.
Другой пример: вы хотите извлечь некоторую информацию из URL-адреса, а затем создать для нее файл utils, содержащий функцию, и импортировать ее при необходимости:
источник