我来自一个有角度的世界,在那里我可以将逻辑提取到服务/工厂,并在控制器中使用它们。
我试图了解如何在React应用程序中实现相同的目标。
假设我有一个可以验证用户密码输入(强度)的组件。它的逻辑非常复杂,因此我不想将其编写在自己的组件中。
我应该在哪里写这个逻辑?在商店中是否使用助焊剂?还是有更好的选择?
我来自一个有角度的世界,在那里我可以将逻辑提取到服务/工厂,并在控制器中使用它们。
我试图了解如何在React应用程序中实现相同的目标。
假设我有一个可以验证用户密码输入(强度)的组件。它的逻辑非常复杂,因此我不想将其编写在自己的组件中。
我应该在哪里写这个逻辑?在商店中是否使用助焊剂?还是有更好的选择?
同样的情况:完成了多个Angular项目并转移到React,没有一种简单的方法可以通过DI提供服务似乎缺少了一点(除了服务的细节)。
使用上下文和ES7 decorator,我们可以接近:
https://jaysoo.ca/2015/06/09/react-contexts-and-dependency-injection/
似乎这些家伙已经朝着另一个方向迈出了一步:
http://blog.wolksoftware.com/dependency-injection-in-react-powered-inversifyjs
仍然感觉像在对抗谷物。在进行重大React项目后的6个月内,将重新讨论该答案。
编辑:6个月后,有了更多的React经验。考虑一下逻辑的性质:
有些还可以重用HOC,但对我来说,以上内容涵盖了几乎所有用例。另外,请考虑使用鸭子来扩展状态管理,以使关注点分离并以用户界面为中心。
请记住,React的目的是更好地耦合逻辑上应该耦合的事物。如果您要设计一个复杂的“验证密码”方法,应该在哪里使用?
那么,您将需要在每次用户需要输入新密码时使用它。这可以在注册屏幕,“忘记密码”屏幕,管理员“为另一个用户重置密码”屏幕等上。
但是在任何一种情况下,它总是与某些文本输入字段相关联。这就是应该将其耦合的地方。
制作一个非常小的React组件,该组件仅由输入字段和关联的验证逻辑组成。在所有可能需要输入密码的表单中输入该组件。
这与为逻辑提供服务/工厂实质上是相同的结果,但是您将其直接耦合到输入。因此,由于它永久地绑定在一起,因此您现在无需告诉该函数在哪里查找其验证输入。
当您意识到Angular服务只是一个提供一组上下文无关方法的对象时,问题变得非常简单。只是Angular DI机制使它看起来更加复杂。DI非常有用,因为它可以为您创建和维护实例,但您实际上并不需要它。
考虑一个流行的AJAX库axios(您可能已经听说过):
import axios from "axios";
axios.post(...);
它不是服务吗?它提供了一组负责某些特定逻辑的方法,并且独立于主代码。
您的示例案例是关于创建一组隔离的方法来验证您的输入(例如,检查密码强度)。有些人建议将这些方法放在组件中,这对我来说显然是一种反模式。如果验证涉及进行和处理XHR后端调用或进行复杂的计算该怎么办?您会将这种逻辑与鼠标单击处理程序和其他特定于UI的东西混合使用吗?废话。与容器/ HOC方法相同。包装您的组件只是为了添加一种方法,该方法将检查值中是否包含数字?来吧。
我将创建一个名为“ ValidationService.js”的新文件,并将其组织如下:
const ValidationService = {
firstValidationMethod: function(value) {
//inspect the value
},
secondValidationMethod: function(value) {
//inspect the value
}
};
export default ValidationService;
然后在您的组件中:
import ValidationService from "./services/ValidationService.js";
...
//inside the component
yourInputChangeHandler(event) {
if(!ValidationService.firstValidationMethod(event.target.value) {
//show a validation warning
return false;
}
//proceed
}
您可以在任何地方使用此服务。如果验证规则更改,则只需要关注ValidationService.js文件。
You may need a more complicated service which depends on other services. In this case your service file may return a class constructor instead of a static object so you can create an instance of the object by yourself in the component. You may also consider implementing a simple singleton for making sure that there is always only one instance of the service object in use across the entire application.
我和你一样穿着靴子。在您提到的情况下,我会将输入验证UI组件实现为React组件。
我同意验证逻辑本身的实现不应(必须)耦合。因此,我将其放入单独的JS模块中。
也就是说,对于不应耦合的逻辑,请使用单独文件中的JS模块/类,并使用require / import将组件与“服务”分离。
这允许依赖项注入和两者的单元测试独立。