组件封装注意事项

https://github.com/YvetteLau/Blog

参考文章

  1. 尽可能低耦合,组件之间的依赖越小越好
    比如不要直接修改父组件状态。
  2. 最好从父级传入所需信息,不要在公共组件中请求数据
  3. 传入数据添加校验
  4. 处理事件的方法写在父组件中
  • 易用性
  • 拓展性
  • 可维护性
  • 可重用性

一个封装组件提供 props 控制其行为而不是暴露其内部结构。

1、封装

耦合:耦合是决定组件之间依赖程度的系统特性

松耦合(易修改、易复用、易测试)

  1. 可以在不影响应用其它部分的情况下对某一块进行修改
  2. 任何组件都可以替换为另一种实现 ?
  3. 在整个应用程序中实现组件复用,从而避免重复代码
  4. 独立组件更容易测试,增加了测试覆盖率

紧耦合

  1. 失去松耦合的好处
  2. 组件高度依赖其他组件时,很难修改

2、信息隐藏

封装良好的组件隐藏其内部结构,并提供一组属性来控制其行为(其他组件不必知道组件的实现细节)
隐藏内部结构的组件彼此之间的依赖性较小,而降低依赖度会带来松耦合的好处

3、通信

组件通信的方法:props

  • prop 可以是一个事件处理函数和异步函数,可以是一个组件构造函数

为了避免破坏封装,请注意通过 props 传递的内容。给子组件设置 props 的父组件不应该暴露其内部结构的任何细节。例如,使用 props 传输整个组件实例或 refs 都是一个不好的做法。访问全局变量同样也会对封装产生负面影响。

4、单一职责原则 SRP(作用:修改隔离,对系统的其他组件产生影响很轻微并且可预测。)

参考文献

当一个组件只有一个改变的原因时,它有一个单一的职责。

为什么只有一个理由可以改变很重要?因为这样组件的修改隔离并且受控。单一职责原则制了组件的大小,使其集中在一件事情上。集中在一件事情上的组件便于编码、修改、重用和测试。

下面我们来举几个例子

  1. 实例 1:一个组件获取远程数据,相应地,当获取逻辑更改时,它有一个更改的原因。

发生变化的原因是:

修改服务器 URL
修改响应格式
要使用其他 HTTP 请求库
或仅与获取逻辑相关的任何修改。

  1. 示例 2:表组件将数据数组映射到行组件列表,因此在映射逻辑更改时有一个原因需要更改。

发生变化的原因是:

你需要限制渲染行组件的数量(例如,最多显示 25 行)
当没有要显示的项目时,要求显示提示信息“列表为空”
或仅与数组到行组件的映射相关的任何修改。

4.1 多重职责陷阱

例如, 同时有两个职责,绘制图表,并处理为该图表提供数据的表单。 就会有两个更改原因:绘制图表和处理表单。
当你更改表单字段(例如,将 修改为 时,你无意中中断图表的渲染。此外,图表实现是不可重用的,因为它与表单细节耦合在一起。

解决多重责任问题需要将 分割为两个组件: 和。每个组件只有一个职责:绘制图表或处理表单。组件之间的通信是通过 props 实现。

4.2 使组件只有一个职责

设想一个组件向一个专门的服务器发出 HTTP 请求,以获取当前天气。成功获取数据时,该组件使用响应来展示天气信息

这个天气组件有两个改变原因:

componentDidMount() 中的 fetch 逻辑:服务器 URL 或响应格式可能会改变。
render() 中的天气展示:组件显示天气的方式可以多次更改。

可分为两个组件,一个组件负责获取天气、提取响应数据并将其保存到 state 中。改变原因:获取数据逻辑改变
另一个组件负责显示天气,改变原因只可能是视觉显示改变

4.3 高阶组件(HOC)偏好单一职责原则

高阶组件是一个接受一个组件并返回一个新组件的函数。

高阶组件常见用法:为封装的组件增加新属性或修改现有属性值(这种技术为属性代理)

function withNewFunctionality(WrappedComponent) {
    return class NewFunctionality extends Component {
        render() {
            const newProp = 'Value';
            const propsProxy = {
                ...this.props,
                // 修改现有属性:
                ownProp: this.props.ownProp + ' was modified',
                // 增加新属性:
                newProp
            };
            return <WrappedComponent {...propsProxy} />;
        }
    }
}
const MyNewComponent = withNewFunctionality(MyComponent);

5、组合和复用

5.1 组合

一个组合式组件是由更小的特定组件组合而成的。

那么组合与单一责任以及封装有什么联系呢?
单一责任原则描述了如何将需求拆分为组件,封装描述了如何组织这些组件,组合描述了如何将整个系统粘合在一起。

好处:通过子组件分别实现单一职责的方式,是组件也符合单一职责原则

优点:

  1. 可重用
    组合有可重用的优点,使用组合的组件可以重用公共逻辑
    可重用的组件符合不重复自己(Don’t repeat yourself)的原则。这种做法可以节省你的精力和时间,并且在后期,有利于代码维护。

  2. 灵活
    在 react 中,一个组合式的组件通过给子组件传递 props 的方式,来控制其子组件。这就带来了灵活性的好处

  3. 高效
    用户界面可组合的层次结构,因此,组件的组合是一种构建用户界面的有效的方式。

5.2 复用

可重用的组件,一次编写多次使用。
代码重复增加了复杂性和维护工作,但没有增加显著的价值。逻辑更新迫使您修改应用程序中的所有重复代码。
只有一个组件符合单一责任原则并且具有合理的封装时,它是可复用的。

6、可测试和经过测试

经过测试的组件验证了其在给定输入的情况下,输出是否符合预期。(可测试意味着良好的设计)
可测试组件易于测试。

  1. 如何确保组件按预期工作?你可以不以为然地说:“我通过手动验证其正确性”。

如果你计划手动验证每个组件的修改,那么迟早,你会跳过这个繁琐的环节,进而导致你的组件迟早会出现缺陷。

这就是为什么自动化组件验证很重要:进行单元测试。单元测试确保每次进行修改时,组件都能正常工作。

单元测试不仅涉及早期错误检测。 另一个重要方面是能够验证组件架构是否合理。

一个不可测试或难以测试的组件很可能设计得很糟糕。

当组件的架构设计很脆弱时,就会变得难以测试,而当组件难以测试的时候,你大概念会跳过编写单元测试的过程,最终的结果就是:组件未测试。

  1. 富有意义

开发人员大部分时间都在阅读和理解代码,而不是实际编写代码。我们花 75%的时间理解代码,花 20%的时间修改现有代码,只有 5%编写新的代码。

在可读性方面花费的额外时间可以减少未来队友和自己的理解时间。当应用程序增长时,命名实践变得很重要,因为理解工作随着代码量的增加而增加。

  • 命名:当名称有意义地暗示意图时,组件易于理解。
  • 注释:组件,方法和变量的有意义的名称足以使代码可读。 因此,注释大多是多余的。
  1. 可靠性很重要
    原文作者:drunk喵咪
    原文地址: https://blog.csdn.net/jdrunk/article/details/116211942
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞