构建React组件最全方法

我非常喜欢使用react,因为我觉得它最大优点就是足够简单。 在简单和容易之间还是存在区别 的,我的意思是react也很简单。当然你需要些时间来了解它,当你掌握其核心内容后,其他的事都是水到渠成的了。下文将介绍比较难的部分。

耦合&内聚

这些指标(耦合&内聚)或多或少的给我们改变编程习惯带了挑战。它们经常被运用在类形式的面向对象编程中。我们也将参考并且运用同样的规则在编写React组件上。

耦合指元素之间的相互连接和依赖关系。如果你改变一个元素需要同步的更新另外一个元素,我们称此为紧密耦合。而松散耦合指的是改变一个元素时,并不需要改变另外一个元素。举个例子,显示银行转账金额功能。如果展示金额依赖于汇率计算,那么内部转换结构更改时,展示的代码也会被更新。如果我们设计基于一个元素接口的,松散耦合的系统,这样元素的改变并不会影响视图层展示。很明显,松散耦合的组件更易于管理和控制。

内聚则是组件是否只为一件事情负责。这个指标是依循单一原则和unix原则:专注一件事情并且做好这件事。如果账户余额格式化展示需要计算相关汇率和检查是否有查阅历史权限,那么这个包含很多功能职责,而这些功能并不相互依赖。也许,权限处理和汇率应该是不同的组件。另一方面,如果有多个组件,一个用于整数部分,一个用于小数部分,另外一个用于货币展示,程序员想展示余额,他们则需要找到所有组件进行组装。其中的挑战则是创造高度内聚的组件。

构建组件

创建组件有很多种方法。我们希望在合理程度下组件是可以被重用的 。我们也希望构建的小组件可以被用在更大的组件中。理想情况下,我们想构建松散耦合和高度聚合的组件,这样我们的系统更有利于管理和扩展。在React组件中props 类似函数中的参数,它们也可以看做是无状态功能的组件。我们需要思考在组件中如何定义props和组件如何被重用。

接下来,我们以费用管理系统为背景,分析费用详细的格式,来介绍如果构建组件:

type Expense {      description: string      category: string      amount: number      doneAt: moment    }

登录后复制

 

根据模型,会有以下几种对费用格式的程序建模方式:

无props

传递一个expense对象

传递必要的属性

传递所有属性的map

传递一个格式化的子对象

下面分别讨论使用上述传递方式的优缺点。不过需要时刻关注使用以上任何方式是要看使用场景和依赖系统的。这也是我们所做的,建立适当的抽象场景。

无props

这是最简单的解决办法,往往就是构建一个写静态数据的组件。

const ExpenseDetails = () => (      

Category: Food

Description: Lunch

Amount: 10.15

Date: 2017-10-12

)

登录后复制

 

不传递props,就不会给我们带来任何灵活性,而且组件也只能用于单一的场景。在费用明细的例子中,我们可以看到,最初组件是需要接受一些props。不过在某些场景下,没有任何props也是一个好的解决方式。首先,我们可以使用一些组件,其props的内容是一些不会轻易更改的内容,比如:商标,logo或者公司信息等。

const Logo = () => (      

DayOne logo

)

登录后复制

 

编写尽可能小的组件使得系统更加容易维护。保持信息只保存在一处而且只需要在一处进行修改。不要在多处写重复的代码。

传递expense对象

在费用明细确定情况下,我们需要给组件传递数据。首先,我们需要传递一个expense对象。

const ExpenseDetails = ({ expense }) => (      

Category: {expense.category}

Description: {expense.description}

Amount: {expense.amount}

Date: {expense.doneAt}

)

登录后复制

 

传递费用对象给费用明细的组件是非常有意义的。费用明细的格式是高度一致的,它显示费用的数据。无论什么时候需要改变格式,这是唯一可以修改的地方。改变费用明细的格式也不会对费用对象自身带来什么副作用。

这个组件是和费用对象紧密耦合,这是一个坏的事情吗?当然不是,但是我们必须意识到这是如何影响我们系统的。 传递一个对象作为props,费用明细的组件将会依赖费用内部结构。当我们改变费用的内部结构时候,我们将需要更改费用明细组件。当然,我们只需要在一处进行修改。

这样的设计如何适应未来的改变呢? 如果我们增加、改变或者删除一个字段,我们将只需改变一个组件。如果我们需要增加一个其他的日历格式化展示?我们可以为日历格式化增加一个新的prop。

const ExpenseDetails = ({ expense, dateFormat }) => (      

Category: {expense.category}

Description: {expense.description}

Amount: {expense.amount}

Date: {expense.doneAt.format(dateFormat)}

)

登录后复制

 

我们开始增加属性来使组件更加灵活。如果只有几个选项,那么一切都是很ok的。系统业务开始扩展后问题就来了,在不同的场景下我们需要维护大量的props。

const ExpenseDetails = ({ expense, dateFormat, withCurrency, currencyFormat, isOverdue, isPaid ... })

登录后复制

 

增加props可以使得组件重用性更好,但你可能设计了多重功能职责的组件。这种规则也同样在函数写法中运用。可以用多个参数来创建一个函数,当参数的数目超过3个或者4个时候,意味着这个函数在做很多事情了,也许这时候应该将函数拆成更小的函数来的更加简单。

随着组件props的增加,我们将其拆分成定义明确的组件,比如:OverdueExpenseDetails, PaidExpenseDetails等。

只传递必要的属性

为了减少对象自身的内容,我们可以只传递必要的属性值。

const ExpenseDetails = ({ category, description, amount, date }) => (      

Category: {category}

Description: {description}

Amount: {amount}

Date: {date}

)

登录后复制

 

我们分别传递属性,这样我们将一部分工作责任转移给了组件使用者。如果费用的内部结构发生变化,他将不会影响费用明细的格式化。但可能影响每个使用组件的地方,因为我们可能需要修改props。当我们以独立的属性传递props时候,一个组件将更加抽象了。

只传递需要的字段对未来设计改动是如何影响的?增加、更新或者删除字段将不会很容易。无论何时我们要增加一个字段,我们不仅仅要改变费用细节的实现,也需要改变每个使用组件的地方。另外一个方面,支持多种日历格式化几乎是现成的,我们可以传递日历作为prop,也可以传递格式化后的日历。


登录后复制

 

决定如何展示特定的字段应该在掌握在具体使用组件的人手中,这将不是费用明细组件关心的内容。

传递map或者array的属性

为了达到组件抽象化,我们可以传递一个map的属性值。

const ExpenseDetails = ({ expense }) => (      

{ _.reduce(expense, (acc, value, key) => { acc.push(

{key}{value}

) }, []) }

)

登录后复制

 

使用组件的人控制费用明细的格式化,传递给组件的对象格式则必须正确。

const expense = {      "Category": "Food",      "Description": "Lunch",      "Amount": 10.15,      "Date": 2017-10-12    }

登录后复制

 

这个方案有很多缺陷,我们很难控制组件展示的样式,并且展示顺序也没有指定。因此,如果我们需要某种顺序的话,可以采用array代替map来解决这个问题。但是仍然还有缺陷。

传递map 和array作为props 不与费用耦合,也根本与它不一致。增加和删除新属性虽然只改变了prop,但是我们无法控制组件本身的格式。如果我们只改变类别的格式化,这不是一个可行的办法。(确切地说,总有一个办法来解决,例如,传递另外一个格式化后的props。这个解决方案似乎不再简单了。)

传递一个格式化的子对象

我们也可以只通过直接传对一个子对象,这样就能考虑更少的组件内需要如何展示。

const ExpenseDetails = ({ children }) => (      

{ children }

)

登录后复制

 

在这种情况下,费用明细只是一个提供结构和样式的容器。展示所有信息则是使用组件的人必须提供的。

      

Category: {expense.category}

Description: {expense.description}

Amount: {expense.amount}

Date: {expense.doneAt}

登录后复制

 

在费用明细这个案例中,我们需要重复许多工作,因此这也许不是一个好的解决方案。尽管如此,灵活性则是巨大的,因为有可能有很多不同的格式化操作。增删改只需要改变使用组件时候传入的值。日期格式也是一样的,我们虽然失去了功能内聚的特点,但这也是我们不得不付出的代价。

环境为王

正如你所看到,我们讨论了它们的不同优缺点和可能性。哪一个最好呢,这取决于:

项目本身

项目阶段

组件自身,需要很多特殊的组件组成还是只需要简单的一些选项值

自己的习惯

使用环境-适合频繁的改变和被多次使用

没有一个万能的解决方案,一个方案也并不能适用所有场景。我们如何构建组件对于系统的维护和系统可扩展方面有着深远的影响。这完全依赖于组件所使用的环境。非常幸运的是,我们有很多可使用的方案。组件是功能的抽象集合,它既能构建小系统也能构建大系统。所以这仅仅只是一个选择问题。

相关推荐:

store优化React组件的方法详解

如何在React组件“外”使用父组件的Props

React组件的生命周期函数是什么

以上就是构建React组件最全方法的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2789514.html

(0)
上一篇 2025年3月8日 18:43:55
下一篇 2025年3月2日 16:27:51

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • JS+canvas动态绘制饼图的方法示例

    这篇文章主要介绍了js+canvas动态绘制饼图的方法,结合具体实例形式分析了js+canvas实现饼状图形绘制的相关操作技巧,对javascript感兴趣的朋友可以参考下本篇文章。 运行效果图如下: 完整代码: nbsp;html>…

    2025年3月8日
    200
  • jQuery实现MD5加密的简单方法

    本文主要介绍了jquery简单实现md5加密的方法,基于jquery.md5.js插件实现md5加密功能,非常简单实用,需要的朋友可以参考下,希望能帮助到大家。 1、问题背景 有两个输入框,一个输入明文,另一个输入框显示密文 2、实现源码 …

    2025年3月8日
    200
  • JS实现多物体运动的方法详解

    这篇文章主要介绍了js实现多物体运动的方法,结合实例形式较为详细的分析了javascript实现多物体运动的原理与相关操作技巧,对javascript感兴趣的朋友可以参考下本篇文章 本文实例分析了JS实现多物体运动的方法。分享给大家供大家参…

    2025年3月8日
    200
  • JS运动改变单物体透明度的方法分析

    这篇文章主要介绍了js运动改变单物体透明度的方法,结合实例形式分析了页面元素属性动态修改相关js操作技巧,对javascript感兴趣的朋友可以参考下本篇文章 除了通过改变物体的 宽,高,letf,top位置或者是运动方向来实现物体运动效果…

    编程技术 2025年3月8日
    200
  • React 和Webpack构建打包优化实例详解

    本文主要介绍了浅谈react + webpack 构建打包优化,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 使用 babel-react-optimize 对 React 代码进行优化 检…

    2025年3月8日
    200
  • Angular2整合其他插件的方法实例详解

    现在有很多朋友在接触angular2的时候,总是不可避免的会使用一些其他的第3方的插件,而这些插件可能都是基于jquery的,而且也没有对应的angular2的版本,这里我就来讲解一下,在这种情况下,如何整合第3方的jquery插件。我们以…

    2025年3月8日
    200
  • jQuery中DOM节点操作方法总结

    本文主要介绍了jquery中 dom节点操作方法大全,感兴趣的朋友一起看看吧,希望能帮助大家更好的学习jquery中dom节点操作方法。 append(content | fn):向每个匹配的元素内部追加内容。 例如:向所有段落中追加一些H…

    编程技术 2025年3月8日
    200
  • React根据宽度自适应高度实例分享

    有时对于响应式布局,我们需要根据组件的宽度自适应高度。css无法实现这种动态变化,传统是用jquery实现。本文主要介绍了react根据宽度自适应高度的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希…

    2025年3月8日
    200
  • JS数组添加元素方法总结

    本篇文章介绍了如何向js数组中添加新的元素,分别使用不同的几种方法去给js数组添加元素,数组在js中是很常用的数据类型之一,而对数组进行操作这是我们必会的基础之一。 下面我们来看一下有哪些方法可以对JS数组进行元素的添加! 在数组的开头添加…

    编程技术 2025年3月8日
    200
  • JS实现汉字按拼音排序的方法

    本文主要介绍了js实现中文汉字按拼音排序的方法,涉及javascript针对中文字符串的转换、遍历、排序等相关操作技巧,需要的朋友可以参考下,希望能帮助到大家。 代码1,拼音排序: var array = [‘武汉’, ‘北京’, ‘上海’…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论