【问题标题】:Private methods in React service function componentReact 服务功能组件中的私有方法
【发布时间】:2022-01-08 05:01:50
【问题描述】:

我对 React 有点陌生,我目前正在开发一个具有服务层的 Proyect。为此,我创建了一个函数组件,它将方法作为变量:

const CustomComponent = () => {
    
    method1 = () => {...},

    method2 = () => {...},

    method3 = () => {...}

}

export default CustomComponent;

这个组件会被导入到使用它的组件中。

为了使我的架构尽可能干净,我想将一些方法设为私有。但是,您可能已经知道,这在我提出的解决方案中是不可能的。 hoy 对如何实现这一点有任何想法,或者可能有一个约定来制作我不知道的服务层?

非常感谢您!

【问题讨论】:

    标签: javascript reactjs architecture service-layer


    【解决方案1】:

    我发现特别干净和可维护的架构是您将逻辑从表示拆分为两个文件,如下所示:

    服务层(ts):

    export class Service implements ServiceInterface {
      constructor(private instanceVariable: string = "foo") { }
    
      private methodOne(): string {
        return this.instanceVariable
      }
    
      public methodTwo(argumentVariable: string): string {
        const importantString = this.methodOne();
        
        return importantString + argumentVariable;
      }
    }
    
    interface ServiceInterface {
      methodTwo(argumentVariable: string): string;
    }
    
    export default new Service();
    

    服务层(js):

    export class Service {
      instanceVariable;
      constructor(contructorArgument) { 
        this.instanceVariable = contructorArgument;
      }
    
      methodOne() {
        return this.instanceVariable
      }
    
      methodTwo(argumentVariable) {
        const importantString = this.methodOne();
        
        return importantString + argumentVariable;
      }
    }
    
    export default new Service();
    

    表示层:

    import Service from "./service.ts";
    
    const FunctionalComponent = () => {
      const [localState, setLocalState] = useState(localStateInit);
    
      return (
        <>
          <div>{Service.methodTwo("bar")}</div>
        </>
      )
    }
    

    这里发生的事情很少(主要是关于 ts 实现)。

    1. 将组件的服务层和表示层保存在单独的文件中。
    2. 使用接口来描述服务类及其方法。这将有助于在组件中使用服务层,因为您将获得 Typescript 的 IntelliSense。
    3. 在本例中,我将服务实例作为默认导出从其文件中导出。这为您在组件文件中提供了一个更清晰的 API,您可以在其中调用方法,而不必通过创建实例来“污染”组件文件。这至少有以下两个缺点:
    • 你大多失去了与静态类成员良好合作的能力
    • 预配置的实例变量(在构造函数中作为私有成员初始化)意味着它的值在测试中不能被替换。

    如果以上任何一个都不行,则清理构造函数,仅导出类本身并在组件文件中根据需要实例化它。

    1. 我也在导出类本身。这是出于测试目的。在测试中,您希望能够交换传递给类的构造函数的参数,并且您需要有类定义才能做到这一点。
    2. 您会注意到在构造函数中声明和实例化私有类变量的简写符号:private instanceVariable: string = "foo"。这相当于这样:
    class Service {
      private instanceVariable: string;
    
      constructor(constructorArgument: string) { 
        this.instanceVariable = constructorArgument;
      }
    

    这种表示法在与依赖注入一起使用时特别好。

    1. 总体而言,此设置将帮助您在服务层中进行单元测试逻辑,因为您可以像测试任何其他类一样对其进行测试。当有很多条件渲染逻辑时,这会特别方便。

    如果这是您一直在寻找的,请告诉我。也许我们可以根据您的用例更好地定制它。

    【讨论】:

    • 哇,没想到这么发达的答案!不过,一个小想法,我没有在我的项目中使用 TypeScript。答案还成立吗?我不确定最新版本的 react 中是否有类。由于更改的数量,文档有点混乱。
    • 实际上,服务层文件根本不会使用 React!它是一个普通的 .js 或 .ts 文件(与使用 jsx 的文件的 .jsx / .tsx 不同)。你需要去掉一些打字稿的好东西,比如接口、类成员修饰符和类型。但答案仍然成立。因为您提到您想使用私有方法,所以我假设您的项目正在使用 typescript,因为 private 关键字在纯 .js 中不可用。另外,我鼓励你在你的项目中使用 Typescript,即使是很小的项目。您可能总是不输入 React 组件并使用它,例如对于所述服务层。
    • 编辑了我的答案以添加服务层的纯 js 版本。 React 组件(表示层)将保持完全一样,因为那里没有使用任何类型。
    • 不客气!我很想知道您的实施进展如何以及您是否能够达到预期的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    相关资源
    最近更新 更多