资讯专栏INFORMATION COLUMN

可靠React组件设计的7个准则之SRP

Charles / 3141人阅读

摘要:编写组件时要考虑的基本准则是单一职责原则。这些更改通常要求组件在隔离状态下易于修改这也是的目标。解决多重责任问题需要将分割为两个组件和。组件之间的通信是通过实现。更改的唯一原因是修改表单字段。

翻译:刘小夕

原文链接:https://dmitripavlutin.com/7-...

原文的篇幅非常长,不过内容太过于吸引我,还是忍不住要翻译出来。此篇文章对编写可重用和可维护的React组件非常有帮助。但因为篇幅实在太长,我不得不进行了分割,本篇文章重点阐述 SRP,即单一职责原则。

————————————我是一条分割线————————————

更多文章可戳: https://github.com/YvetteLau/...

我喜欢React组件式开发方式。你可以将复杂的用户界面分割为一个个组件,利用组件的可重用性和抽象的DOM操作。

基于组件的开发是高效的:一个复杂的系统是由专门的、易于管理的组件构建的。然而,只有设计良好的组件才能确保组合和复用的好处。

尽管应用程序很复杂,但为了满足最后期限和意外变化的需求,你必须不断地走在架构正确性的细线上。你必须将组件分离为专注于单个任务,并经过良好测试。

不幸的是,遵循错误的路径总是更加容易:编写具有许多职责的大型组件、紧密耦合组件、忘记单元测试。这些增加了技术债务,使得修改现有功能或创建新功能变得越来越困难。

编写React应用程序时,我经常问自己:

如何正确构造组件?

在什么时候,一个大的组件应该拆分成更小的组件?

如何设计防止紧密耦合的组件之间的通信?

幸运的是,可靠的组件具有共同的特性。让我们来研究这7个有用的标准(本文只阐述 SRP,剩余准则正在途中),并将其详细到案例研究中。

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

编写React组件时要考虑的基本准则是单一职责原则。单一职责原则(缩写:SRP)要求组件有一个且只有一个变更的原因。

组件的职责可以是呈现列表,或者显示日期选择器,或者发出 HTTP 请求,或者绘制图表,或者延迟加载图像等。你的组件应该只选择一个职责并实现它。当你修改组件实现其职责的方式(例如,更改渲染的列表的数量限制),它有一个更改的原因。

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

下面我们来举几个例子

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

发生变化的原因是:

修改服务器URL

修改响应格式

要使用其他HTTP请求库

或仅与获取逻辑相关的任何修改。

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

发生变化的原因是:

你需要限制渲染行组件的数量(例如,最多显示25行)

当没有要显示的项目时,要求显示提示信息“列表为空”

或仅与数组到行组件的映射相关的任何修改。

你的组件有很多职责吗?如果答案是“是”,则按每个多带带的职责将组件分成若干块。

如果您发现SRP有点模糊,请阅读本文。
在项目早期阶段编写的单元将经常更改,直到达到发布阶段。这些更改通常要求组件在隔离状态下易于修改:这也是 SRP 的目标。

1.1 多重职责陷阱

当一个组件有多个职责时,就会发生一个常见的问题。乍一看,这种做法似乎是无害的,并且工作量较少:

你立即开始编码:无需识别职责并相应地规划结构

一个大的组件可以做到这一切:不需要为每个职责创建组成部分

无拆分-无开销:无需为拆分组件之间的通信创建 propscallbacks

这种幼稚的结构在开始时很容易编码。但是随着应用程序的增加和变得复杂,在以后的修改中会出现困难。同时实现多个职责的组件有许多更改的原因。现在出现的主要问题是:出于某种原因更改组件会无意中影响同一组件实现的其它职责。

不要关闭电灯开关,因为它同样作用于电梯。

这种设计很脆弱。意外的副作用是很难预测和控制的。

例如, 同时有两个职责,绘制图表,并处理为该图表提供数据的表单。 就会有两个更改原因:绘制图表和处理表单。

当你更改表单字段(例如,将 修改为

); } handleChange(event) { this.setState({ inputValue: event.target.value }); } handleClick() { localStorage.setItem("inputValue", this.state.inputValue); } }

遗憾的是: 有2个职责:管理表单字段;将输如只保存中 localStorage

让我们重构一下 组件,使其只有一个职责:展示表单字段和附加的事件处理程序。它不应该知道如何直接使用存储:

class PersistentForm extends Component {
    constructor(props) {
        super(props);
        this.state = { inputValue: props.initialValue };
        this.handleChange = this.handleChange.bind(this);
        this.handleClick = this.handleClick.bind(this);
    }

    render() {
        const { inputValue } = this.state;
        return (
            
); } handleChange(event) { this.setState({ inputValue: event.target.value }); } handleClick() { this.props.saveValue(this.state.inputValue); } }

组件从属性初始值接收存储的输入值,并使用属性函数 saveValue(newValue) 来保存输入值。这些props 由使用属性代理技术的 withpersistence() HOC提供。

现在 符合 SRP。更改的唯一原因是修改表单字段。

查询和保存到本地存储的职责由 withPersistence() HOC承担:

function withPersistence(storageKey, storage) {
    return function (WrappedComponent) {
        return class PersistentComponent extends Component {
            constructor(props) {
                super(props);
                this.state = { initialValue: storage.getItem(storageKey) };
            }

            render() {
                return (
                    
                );
            }

            saveValue(value) {
                storage.setItem(storageKey, value);
            }
        }
    }
}

withPersistence()是一个 HOC,其职责是持久的。它不知道有关表单域的任何详细信息。它只聚焦一个工作:为传入的组件提供 initialValue 字符串和 saveValue() 函数。

withpersistence() 一起使用可以创建一个新组件。它与本地存储相连,可以在应用程序中使用:

const LocalStoragePersistentForm
    = withPersistence("key", localStorage)(PersistentForm);

const instance = ;

只要 正确使用 initialValuesaveValue()属性,对该组件的任何修改都不能破坏 withPersistence() 保存到存储的逻辑。

反之亦然:只要 withPersistence() 提供正确的 initialValuesaveValue(),对 HOC 的任何修改都不能破坏处理表单字段的方式。

SRP的效率再次显现出来:修改隔离,从而减少对系统其他部分的影响。

此外,代码的可重用性也会增加。你可以将任何其他表单 连接到本地存储:

const LocalStorageMyOtherForm
    = withPersistence("key", localStorage)(MyOtherForm);

const instance = ;

你可以轻松地将存储类型更改为 session storage

const SessionStoragePersistentForm
    = withPersistence("key", sessionStorage)(PersistentForm);

const instance = ;

初始版本 没有隔离修改和可重用性好处,因为它错误地具有多个职责。

在不好分块组合的情况下,属性代理和渲染劫持的 HOC 技术可以使得组件只有一个职责。

谢谢各位小伙伴愿意花费宝贵的时间阅读本文,如果本文给了您一点帮助或者是启发,请不要吝啬你的赞和Star,您的肯定是我前进的最大动力。 https://github.com/YvetteLau/...
关注公众号,加入技术交流群。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106528.html

相关文章

  • 可靠React组件设计7准则终篇

    摘要:单元测试不仅涉及早期错误检测。当组件的架构设计很脆弱时,就会变得难以测试,而当组件难以测试的时候,你大概念会跳过编写单元测试的过程,最终的结果就是组件未测试。可测试性是确定组件结构良好程度的实用标准。可复用的组件是精心设计的系统的结果。 翻译:刘小夕原文链接:https://dmitripavlutin.com/7-... 本篇文章重点阐述可测试和富有意义。因水平有限,文中部分翻译可...

    jasperyang 评论0 收藏0
  • 可靠React组件设计7准则组合和复用

    摘要:幸运的是,组合易于理解。组件的组合是自然而然的。高效用户界面可组合的层次结构,因此,组件的组合是一种构建用户界面的有效的方式。这个原则建议避免重复。只有一个组件符合单一责任原则并且具有合理的封装时,它是可复用的。 翻译:刘小夕原文链接:https://dmitripavlutin.com/7-... 原文的篇幅非常长,不过内容太过于吸引我,还是忍不住要翻译出来。此篇文章对编写可重用和...

    Amos 评论0 收藏0
  • 可靠React组件设计7准则封装

    摘要:组件可以处理其他组件的实例化为了避免破坏封装,请注意通过传递的内容。因此,将状态管理的父组件实例传递给子组件会破坏封装。让我们改进两个组件的结构和属性,以便恢复封装。组件的可重用性和可测试性显著增加。 翻译:刘小夕原文链接:https://dmitripavlutin.com/7-... 原文的篇幅非常长,不过内容太过于吸引我,还是忍不住要翻译出来。此篇文章对编写可重用和可维护的Re...

    yck 评论0 收藏0
  • 提升你CSS姿势

    摘要:父类为,代表着一系列文章的列表。对于可读性较好地与代码,不应该像一本书,而应该像一个故事,一个故事中会存在角色和角色之间的关系,而这种更多的语义化地可以较好地提示你整个代码的可维护性。无论哪种文件组织方式比较顺眼,你都应该遵循统一的原则。 原文地址。本文从属于Web 前端入门与最佳实践。 CSS的学习是一个典型的低门槛,高瓶颈的过程,第一次接触CSS的时候觉得一切是如此简单,直到后面越...

    dingding199389 评论0 收藏0
  • 第6章:可维护性软件构建方法 6.1可维护性度量和构造原则

    摘要:设计方案的容易改变这就是所谓的软件构建的可维护性,可扩展性和灵活性。这也可能表明类型或方法可能难以维护。基于源代码中不同运算符和操作数的数量的合成度量。对修改的封闭这种模块的源代码是不可侵犯的。 大纲 软件维护和演变可维护性度量模块化设计和模块化原则OO设计原则:SOLIDOO设计原则:GRASP总结 软件维护和演变 什么是软件维护? 软件工程中的软件维护是交付后修改软件产品以纠正故障...

    chanjarster 评论0 收藏0

发表评论

0条评论

Charles

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<