编写用于React组件的API,第5部分:使用组合

为React组件编写API,第1部分:不要创建冲突的道具

编写用于React组件的API,第2部分:为行为命名,而非交互

为React组件编写API,第3部分:道具的顺序很重要

编写用于React组件的API,第4部分:当心提示!

编写用于React组件的API,第5部分:使用组合

我们为React组件编写API,第6部分:在组件之间创建通信

我们有一个图标组件:


徽章1


<Badge count={12} /> 

您在各种应用程序中看到了它们,它们将对象的数量显示为数字。


github-1


宇宙徽章(图标)在每种特定情况下(信息,危险等)都有几种颜色


徽章2


 <Badge count={12} appearance="information" /> <Badge count={12} appearance="success" /> <Badge count={12} appearance="default" /> <Badge count={12} appearance="warning" /> <Badge count={12} appearance="danger" /> 

该用户界面还有另一个类似的组件Label


github-2


每个上下文还具有几种颜色:


标签2


 <Label text="private" appearance="information" /> <Label text="private" appearance="success" /> <Label text="private" appearance="default" /> <Label text="private" appearance="warning" /> <Label text="private" appearance="danger" /> 

看一下这两个组件,并说一说它们的API(关于其道具)有好有坏


一起2


 <Badge count={12} appearance="information" /> <Label text="private" appearance="information" /> 

有什么好处


两个组件都具有相同的外观道具: appearance ,太好了。 而且,此道具有相同的选择! 如果您知道如何在Badge使用appearance ,那么您已经知道如何在Label使用appearance


力争在组件之间保持一致的道具

编写用于React组件的API的技巧2 ,第2部分:给行为命名,而非交互

什么不好


他们表达其含义的方式是不同的。 他们都有自己的选择。


Badge组件的框架内进行计数, count和处理是有意义的,但是考虑到所有其他组件,这是团队和用户(开发人员)必须记住的附加API。


让我们改善这个API


为了保持一致,我将这个prop content称为,这是我能想到的最常见的名称-比标签,文本或值更笼统。


一起2


 <Badge content="12" appearance="information" /> <Label content="private" appearance="information" /> 

我们丢失了一些细节,但保持了很多一致性。 我们仍然可以使用prop-types设置值类型 ,所以我认为这是一个很好的折衷方案。


但是,等等,在React中已经有了一个多功能的content道具,它被称为children -一个子代。


不要重props.children.

如果您已经定义了接受不基于数据结构的任意数据的道具,那么最好使用组合- 布伦特·杰克逊

这是本文的技巧- 在构图和道具之间进行选择时,请选择构图


让我们用children ,children重构这个API:


一起2


 <Badge appearance="information">12 </Badge> <Label appearance="information">Private </Label> 

看起来很棒


奖励:当您使用children而不是道具时,使用此组件的开发人员无需更改组件即可获得更大的灵活性。


例如,这 ,我要在文本前面添加一个图标。


警觉


使用children我可以在此 添加一个图标,而无需返回此组件或对其进行更改。


 //  -     <Alert type="warning" icon="warning" text="This is an important message!" /> //  <Alert type="warning"> <Icon name="warning" /> This is an important message! </Alert> 

巧合的是,当我写这篇文章时,我看到了Brad Frost的一条推文


嘿,React朋友,需要一点帮助。 我继续遇到这种模式,其中某些组件(尤其是列表)可以拆分为较小的组件,也可以通过传递对象来控制。 哪个选项更好?

代号


看起来很熟悉吗?


首先,我们不要使用prop text而要使用children


 //  : <Breadcrumb text="Home" href="/child" /> //  : <Breadcrumb href="/child">Home</Breadcrumb> 

现在我们已经弄清楚了,让我们谈谈这两个API选项。


不难猜测,我喜欢第一个。


  1. 您无需考虑使用什么道具- text被称为? label这些只是children
  2. 您可以根据需要添加classNametarget 。 对于第二个选项,您需要确保它支持这些属性或将它们简单地传递给基本元素。
  3. 这使您可以将子级包装在上下文中或更高级别的组件中。

规则的例外:


如果Brad想阻止开发人员进行我上面提到的任何设置怎么办? 在这种情况下,给开发人员更大的灵活性将是一个错误!


这是我对布拉德的回答


更多例子


这是我的最后一个最喜欢的示例,它提供了一些更多有关本技巧如何改进您的代码的示例。


表单是一个很好的用法示例,我们想控制表单的布局,显示错误等。 但是同时,我们不想失去扩展的机会。


 // #1  <FormTextInput type="text" label="Name" id="name-input" /> //     id, //  label   input? // #2  <FormField> <Label>Field label</Label> <TextInput id="name-input" type="text" placeholder="What's your name?" /> </FormField> // #3    <FormField label="Field label"> <TextInput id="name-input" type="text" placeholder="What's your name?" /> </FormField> 

后一个示例特别有趣。


有时您需要一个可以在非常不同的情况下使用的组件。 要使组件灵活且仍具有简单的API并不容易。


这就是抢救控制权的地方-让组件的用户决定渲染什么。 在React世界中,此模式称为render prop pattern


render prop组件采用一个函数,该函数返回React元素并调用它,而不是实现自己的渲染。

来自React文档Render-props

渲染道具最流行的示例之一是官方的Context API。


在下面的示例中, App组件控制数据,但不控制其呈现;它将控件传递给Counter组件。


 //    const MyContext = React.createContext() //    //    function App() { return ( <MyContext.Provider value="5"> <Counter /> </MyContext.Provider> ) } //    //   function Counter() { return ( <MyContext.Consumer> {value => ( <div className="counter">the count is: {value}</div> )} </MyContext.Consumer> ) } 

您是否注意到此Consumer API中有什么有趣的东西?


他没有创建新的API,而是使用children接受一个告诉他如何渲染的函数!


 //  <Consumer render={value => ( <div className="counter">the count is: {value}</div> )} /> //  <Consumer> {value => ( <div className="counter">the count is: {value}</div> )} </Consumer> 

返回您的代码,找到可以轻松使用children ,可以接受任何道具的组件。

Source: https://habr.com/ru/post/zh-CN459416/


All Articles