原文的篇幅非常长,不过内容太过于吸引我,还是忍不住要翻译出来。此篇文章对编写可重用和可维护的React组件非常有帮助。但因为篇幅实在太长,我对文章进行了分割,本篇文章重点阐述 封装。因本人水平有限,文中部分翻译可能不够准确,如果您有更好的想法,欢迎在评论区指出。

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

封装

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

耦合是决定组件之间依赖程度的系统特性。根据组件的依赖程度,可区分两种耦合类型:

当应用程序组件对其他组件知之甚少或一无所知时,就会发生松耦合。

当应用程序组件知道彼此的许多详细信息时,就会发生紧耦合。

松耦合是我们设计应用结构和组件之间关系的目标。

松耦合应用(封装组件)

松耦合会带来以下好处:

可以在不影响应用其它部分的情况下对某一块进行修改。、

任何组件都可以替换为另一种实现

在整个应用程序中实现组件复用,从而避免重复代码

独立组件更容易测试,增加了测试覆盖率

相反,紧耦合的系统会失去上面描述的好处。主要缺点是很难修改高度依赖于其他组件的组件。即使是一处修改,也可能导致一系列的依赖组件需要修改。

紧耦合应用(组件无封装)

封装 或 信息隐藏 是如何设计组件的基本原则,也是松耦合的关键。

信息隐藏

封装良好的组件隐藏其内部结构,并提供一组属性来控制其行为。

隐藏内部结构是必要的。其他组件没必要知道或也不依赖组件的内部结构或实现细节。

React 组件可能是函数组件或类组件、定义实例方法、设置 ref、拥有 state 或使用生命周期方法。这些实现细节被封装在组件内部,其他组件不应该知道这些细节。

隐藏内部结构的组件彼此之间的依赖性较小,而降低依赖度会带来松耦合的好处。

通信

细节隐藏是隔离组件的关键。此时,你需要一种组件通信的方法:props。porps 是组件的输入。

建议 prop 的类型为基本数据(例如,string 、 number 、boolean):

;

必要时,使用复杂的数据结构,如对象或数组:

prop 可以是一个事件处理函数和异步函数:

prop 甚至可以是一个组件构造函数。组件可以处理其他组件的实例化:

function If({ component: Component, condition }) {

return condition ? : null;

}

为了避免破坏封装,请注意通过 props 传递的内容。给子组件设置 props 的父组件不应该暴露其内部结构的任何细节。例如,使用 props 传输整个组件实例或 refs 都是一个不好的做法。

访问全局变量同样也会对封装产生负面影响。

案例研究:封装修复

组件的实例和状态对象是封装在组件内部的实现细节。因此,将状态管理的父组件实例传递给子组件会破坏封装。

我们来研究一下这种情况。

一个简单的应用程序显示一个数字和两个按钮。第一个按钮增加数值,第二个按钮减少数值:

这个应用由两个组件组成: 和 .

number 是 的 state 对象, 负责 将这个数字渲染到页面。

// 问题: 封装被破坏

class App extends Component {

constructor(props) {

super(props);

this.state = { number: 0 };

}

render() {

return (

{this.state.number}

);

}

}

负责渲染按钮,并为其设置事件处理函数,当用户点击按钮时,父组件的状态将会被更新:number 加1或者减1((updateNumber()方法`)

// 问题: 使用父组件的内部结构

class Controls extends Component {

render() {

return (

this.updateNumber(+1)}>

Increase

this.updateNumber(-1)}>

Decrease

);

}

updateNumber(toAdd) {

this.props.parent.setState(prevState => ({

number: prevState.number + toAdd

}));

}

}

当前的实现有什么问题?

第一个问题是: 的封装被破坏,因为它的内部结构在应用中传递。 错误地允许 直接去修改其 state。

第二个问题是: 子组件 Controls 知道了太多父组件 的内部细节,它可以访问父组件的实例,知道父组件是一个有状态组件,知道父组件的 state 对象的细节(知道 number 是父组件 state 的属性),并且知道怎么去更新父组件的 state.

一个麻烦的结果是: 将很难测试和重用。对 结构的细微修改会导致需要对 进行修改(对于更大的应用程序,也会导致类似耦合的组件需要修改)。

解决方案是设计一个方便的通信接口,考虑到松耦合和封装。让我们改进两个组件的结构和属性,以便恢复封装。

只有组件本身应该知道它的状态结构。 的状态管理应该从 (updateNumber()方法)移到正确的位置:即 组件中。

被修改为 设置属性 onIncrease 和 onDecrease。这些是更新 状态的回调函数:

// 解决: 恢复封装

class App extends Component {

constructor(props) {

super(props);

this.state = { number: 0 };

}

render() {

return (

{this.state.number}

onIncrease={() => this.updateNumber(+1)}

onDecrease={() => this.updateNumber(-1)}

/>

);

}

updateNumber(toAdd) {

this.setState(prevState => ({

number: prevState.number + toAdd

}));

}

}

现在, 接收用于增加和减少数值的回调,注意解耦和封装恢复时: 不再需要访问父组件实例。也不会直接去修改父组件的状态。

而且, 被修改为了一个函数式组件:

// 解决方案: 使用回调函数去更新父组件的状态

function Controls({ onIncrease, onDecrease }) {

return (

Increase

Decrease

);

}

组件的封装已经恢复,状态由其本身管理,也应该如此。

此外, 不在依赖 的实现细节,onIncrease 和 onDecrease 在按钮被点击的时候调用, 不知道(也不应该知道)这些回调的内部实现。

组件的可重用性和可测试性显著增加。

的复用变得很容易,因为它除了需要回调,没有其它依赖。测试也变得简单,只需验证单击按钮时,回调是否执行。

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

推荐关注本人公众号

react组件设计原则_可靠React组件设计的7个准则之封装相关推荐

  1. 十条设计原则教你学会如何设计网页布局

    网页常见的布局有很多种,单列布局,多列布局.其中单列布局是国外很多网站比较常用的.咱们很多站长以及门户网站都使用的是是两列布局,很少用三列布局的. 下面我来分享下我们常用的网页布局格式以及设计技巧. ...

  2. API设计原则 - Qt官网的设计实践总结

    原文链接:API Design Principles - Qt Wiki 基于Gary的影响力上 Gary Gao 的译文稿:C++的API设计指导 译文发在酷壳 - CoolShell:API设计原 ...

  3. 网页成品——手表商城网站模板源码(17页) web期末作业设计网页_手表商城网页设计作业成品

    HTML5期末大作业:手表商城网站设计--手表商城网站模板源码(17页) web期末作业设计网页_手表商城网页设计作业成品 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. 宠物 ...

  4. HTML5期末大作业:手表商城网站设计——手表商城网站模板源码(17页) web期末作业设计网页_手表商城网页设计作业成品

    HTML5期末大作业:手表商城网站设计--手表商城网站模板源码(17页) web期末作业设计网页_手表商城网页设计作业成品 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. 宠物 ...

  5. 网页作业HTML+CSS+JS大作业——汽车租赁(47页) 加特效 web期末作业设计网页_汽车大学生网页设计作业成品

    HTML+CSS+JS大作业--汽车租赁(47页) 加特效 web期末作业设计网页_汽车大学生网页设计作业成品 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. ...

  6. HTML+CSS+JS大作业——汽车租赁(47页) 加特效 web期末作业设计网页_汽车大学生网页设计作业成品

    HTML+CSS+JS大作业--汽车租赁(47页) 加特效 web期末作业设计网页_汽车大学生网页设计作业成品 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. ...

  7. react 把前后台的axios请求放在一起_可靠React组件设计的7个准则之SRP

    我喜欢React组件式开发方式.你可以将复杂的用户界面分割为一个个组件,利用组件的可重用性和抽象的DOM操作. 基于组件的开发是高效的:一个复杂的系统是由专门的.易于管理的组件构建的.然而,只有设计良 ...

  8. react 代码编写原则_如何编写易读的React代码— 10种编码风格技巧

    react 代码编写原则 by Nirmalya Ghosh 由Nirmalya Ghosh 如何编写易读的React代码- 10种编码风格技巧 (How to write highly readab ...

  9. 前段react技术架构图_基于 React 的可视化编辑平台实践

    前言 前段时间发在朋友圈的一句话:各种自主搭建的平台,想起好多年各种DIY博客,行业门户网站,本质不变,变的是实现的手段了. 正文从这开始-- 本文主要介绍了基于 React 构建可视化编辑平台的实践 ...

  10. react做h5 例子_使用React写一个网站的心得体会

    网站是毕业设计的作品,开发这个网站的目的主要用于记录一些笔记,以及聚合一些资讯信息,也算自己在网络世界中的一块静地吧,可以在这里一些技术上想法的实践. 网站最初前端使用vue开发,在前段时间由于项目的 ...

最新文章

  1. 【OC语法快览】四、基础内存管理
  2. Tango+Daydream,刀剑合璧的Android VR开发
  3. 两个音轨合并_两个双音轨mkv视频合并保持原双音轨不变 MKV怎么合并视频,合并之后仍保留MKV的双音轨...
  4. 并查集的补集 (关押罪犯)
  5. 数据库和python的结合_redis数据库及与python交互用法简单示例
  6. 一文让你读懂Macbook的使用技巧及命令
  7. Swift3.0:Get/Post同步和异步请求
  8. PSP2000远程无线连接控制电脑
  9. JAVA编译器eclipse的安装教程
  10. 安装React脚手架
  11. 云原生架构下的 API 网关实践: Kong (三)
  12. 擦地机器人排行榜_拖地扫地机器人十大品牌排行榜哪个牌子好
  13. 【数据结构】共享栈详解 判断共享栈满条件栈顶指针变化详解记忆方法例题
  14. Android okHttp封装库(2) -- okhttp-OkGo
  15. 【2020年天梯赛—校内选拔赛】7-8 悄悄关注
  16. 新概念二=句子基本结构
  17. 微信小程序console打印json数据
  18. 【笔记】寻路技术整合
  19. psychopy写stroop实验
  20. 投资合伙人股份分配_合伙人股权分配,你必须知道的三大要点!

热门文章

  1. Feb23 小白《linux就该这么学》学习笔记5
  2. Python数据分析学习系列 六 数据加载、存储与文件格式
  3. 华为nova2s云相册在哪里_华为nova2s截频图片在哪个文件夹 | 手游网游页游攻略大全...
  4. 【EXCEL】表格中固定行列 冻结窗口怎么是灰色的
  5. sql优化之终极方案
  6. 《The Selfish Giant》
  7. 右移一位和除二的区别
  8. S7-1200使用集成库FB285控制G120变频器的基本步骤
  9. Java实现八皇后问题
  10. 论坛数据库的几种建表----年度项目拙计有感(前半部分转)