从Angular到React - 如何将业务逻辑与组件分离?

时间:2018-06-04 23:26:32

标签: angular reactjs redux

来自Angular的人的主要问题是如何正确地将业务逻辑与表示分离。我不希望它在组件内部,因此在Angular中我们只创建了服务层,我们存储了逻辑,并通过依赖注入访问了这些服务。

由于react是函数式编程,我想知道从视图(组件)构建和解耦逻辑的最佳实践是什么?

假设我有身份验证服务,我使用OIDC对Identity Server进行身份验证。我在Angular中有一个类和多个函数。

export class LoginComponent{
_authService: AuthService;
constructor(){authService: AuthService}

login():void {
let result= _authService.login("user", "password);
}
}

如何在React中解耦逻辑?假设我在authService中有10个方法,制作相当庞大的类,或者如果我分离到较小的类,如何链接所有这些?我读到了HOC模式,容器模式和redux(动作和调度程序)以及经典模块导出和存储功能(也就是帮助程序)。我不确定助手是不是很好的做法。

有标准还是混合所有?

我主要在互联网上看到教程,其中只有基本语法,而不是真正的应用程序和解耦结构。

1 个答案:

答案 0 :(得分:2)

首先,角度是(至少不仅仅是反应)MVC框架,这就是它提供处理视图和逻辑的工具的原因。 React是一个纯粹的观点'框架,因此它不会假设您的业务逻辑如何工作,也不提供任何工具。为了处理您的模型,您可以使用reduxmobx之类的内容,或者您​​可以构建自己的架构,通常会遵循flux pattern。虽然Redux基于函数式编程的概念,但React不是纯函数式的,也不强制执行任何函数式。但我建议使用函数式编程概念!

现在的最佳做法'显然非常自以为是,并且在很大程度上取决于您的应用程序的规模。所以我认为你找不到单一答案关于"对"做到这一点的方法是。

我个人喜欢将Redux用于我的状态管理(逻辑),这是你从React获得的MC部分。如果将所有应用程序状态放在Redux中,并通过调度操作对其进行修改,那么您的组件就不必了解业务逻辑中的任何内容。这是容器模式可能有用的地方。从这里你得到以下

  • 智能组件了解redux并与之互动。因此,他们可以访问您的模型状态,并在模型上调度操作。
  • 哑组件对您的模型状态一无所知。它们应该根据你传递给它的道具进行纯粹的渲染!

如果严格遵循容器模式,您将体验到视图调试变得更加容易,因为每个组件都是根据您传递给它的道具严格渲染的。因此,这将为您提供以下组件和逻辑的分离。

您的业务逻辑< - >智能组件< - >愚蠢的组件

现在,您可以获得一些示例代码

让我们创建一些非常简单的"逻辑"

class logic  {      
  constructor(value) {
    this.importantVariable = value;
  }

  importantOperation = () => new logic(this.importantVariable + 1);
}

接下来让我们创建一个智能组件,负责将逻辑解析为哑组件

class SomeSmartComponent extends React.Component {      
  constructor(props) {
    super(props)
    this.state = {logic: new logic(1)};
  }

  logicOperation = () => this.setState({logic: this.state.logic.importantOperation()});

  render() {
    return (
      <SomeDumbComponent 
        importantLogicVariable={this.state.logic.importantVariable}
        onClick={this.logicOperation}/>
    );
  }
}

最后,我们可以创建一个哑元组件,根据我们传递它的道具呈现我们的逻辑

class SomeDumbComponent extends React.Component {
  render() {
    return (
      <div>
        <div>I know nothing about the application state</div>
        <div>However i have a prop with value: <b>{this.props.importantLogicVariable}</b></div>
        <div>And i can invoke actions by a button press</div>
        <button 
          type="button"
          onClick={this.props.onClick}>
          Do something
        </button>
       </div>
    );
  }
}

请注意,哑组件不了解我们的业务逻辑。它只是显示我们传递给它的一些信息。即使我们调用的逻辑函数对哑组件是透明的,它只是知道当单击按钮时,它应该调用&#34;某些东西&#34;。那是什么,纯粹基于我们作为道具传承的功能。

您还可以see it in action here