我来自angular世界,在那里我可以提取逻辑到服务/工厂,并在我的控制器中使用它们。
我试图了解如何在React应用程序中实现相同的功能。
假设我有一个验证用户密码输入的组件(它的强度)。它的逻辑相当复杂,因此我不想把它写在组件中。
我应该把这个逻辑写在哪里?如果我在商店里使用助焊剂?还是有更好的选择?
我来自angular世界,在那里我可以提取逻辑到服务/工厂,并在我的控制器中使用它们。
我试图了解如何在React应用程序中实现相同的功能。
假设我有一个验证用户密码输入的组件(它的强度)。它的逻辑相当复杂,因此我不想把它写在组件中。
我应该把这个逻辑写在哪里?如果我在商店里使用助焊剂?还是有更好的选择?
当前回答
我也来自Angular.js领域,React.js中的服务和工厂更简单。
你可以像我一样使用普通的函数或类,回调样式和事件Mobx:)
// Here we have Service class > dont forget that in JS class is Function class HttpService { constructor() { this.data = "Hello data from HttpService"; this.getData = this.getData.bind(this); } getData() { return this.data; } } // Making Instance of class > it's object now const http = new HttpService(); // Here is React Class extended By React class ReactApp extends React.Component { state = { data: "" }; componentDidMount() { const data = http.getData(); this.setState({ data: data }); } render() { return <div>{this.state.data}</div>; } } ReactDOM.render(<ReactApp />, document.getElementById("root")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> </body> </html>
这里有一个简单的例子:
其他回答
请记住,React的目的是更好地耦合逻辑上应该耦合的东西。如果您正在设计一个复杂的“验证密码”方法,它应该耦合在哪里?
每次用户需要输入新密码时,你都需要用到它。这可能出现在注册屏幕、“忘记密码”屏幕、管理员“为其他用户重置密码”屏幕等。
但在这些情况下,它总是会绑定到某个文本输入域。这就是它们应该耦合的地方。
制作一个非常小的React组件,只包含一个输入字段和相关的验证逻辑。在所有可能需要密码输入的表单中输入该组件。
这本质上与为逻辑提供服务/工厂的结果相同,但您将其直接耦合到输入。因此,现在您永远不需要告诉该函数在哪里查找它的验证输入,因为它是永久地绑定在一起的。
我和你处境相同。在你提到的情况下,我将输入验证UI组件实现为一个React组件。
我同意验证逻辑本身的实现应该(必须)不耦合。因此,我会把它放在一个单独的JS模块中。
也就是说,对于不应该耦合的逻辑,在单独的文件中使用JS模块/类,并使用require/import将组件与“服务”解耦。
这允许独立地进行依赖注入和单元测试。
或者你可以将类继承“http”注入到React组件中
通过道具对象。
更新: ReactDOM。render(<ReactApp data={app} />, document.getElementById('root')); 简单地像这样编辑React组件ReactApp: 类ReactApp扩展了React。组件{ 状态= { 数据:“ } 呈现(){ 回报( < div > {this.props.data.getData ()} < / div > ) } }
Service并不局限于Angular,甚至在Angular2+中也是如此,
Service只是helper函数的集合…
有很多方法可以创建它们并在应用程序中重用它们……
1)它们可以都是从js文件导出的分离函数,如下所示:
export const firstFunction = () => {
return "firstFunction";
}
export const secondFunction = () => {
return "secondFunction";
}
//etc
2)我们也可以使用工厂方法,比如函数的集合…在ES6中,它可以是一个类而不是函数构造函数:
class myService {
constructor() {
this._data = null;
}
setMyService(data) {
this._data = data;
}
getMyService() {
return this._data;
}
}
在这种情况下,你需要用new key创建一个实例…
const myServiceInstance = new myService();
同样,在这种情况下,每个实例都有自己的生命周期,所以如果你想跨界共享它要小心,在这种情况下,你应该只导出你想要的实例……
3)如果你的函数和utils不会被共享,你甚至可以把它们放在React组件中,在这种情况下,就像函数在React组件中一样…
class Greeting extends React.Component {
getName() {
return "Alireza Dezfoolian";
}
render() {
return <h1>Hello, {this.getName()}</h1>;
}
}
4)另一种你可以处理事情的方法,可以使用Redux,它是你的临时存储,所以如果你在你的React应用程序中有它,它可以帮助你使用许多getter setter函数…它就像一个大的存储,可以跟踪你的状态,并可以在你的组件之间共享它,所以可以摆脱我们在服务中使用的getter setter的许多痛苦……
做一个DRY代码总是好的,不要重复需要使用的东西来让代码可重用和可读,但不要试图在React应用中遵循Angular的方法,就像第4项提到的,使用Redux可以减少你对服务的需求,你可以限制在一些可重用的帮助函数上使用它们,比如第1项……
我需要一些可以在多个组件间共享的格式化逻辑,而作为Angular开发人员,我自然也倾向于使用服务。
我通过将其放在一个单独的文件中来共享逻辑
function format(input) {
//convert input to output
return output;
}
module.exports = {
format: format
};
然后把它作为一个模块导入
import formatter from '../services/formatter.service';
//then in component
render() {
return formatter.format(this.props.data);
}