为React组件编写API,第1部分:不要创建冲突的道具
编写用于React组件的API,第2部分:为行为命名,而非交互
为React组件编写API,第3部分:道具的顺序很重要
编写用于React组件的API,第4部分:当心提示!
编写用于React组件的API,第5部分:使用组合
我们为React组件编写API,第6部分:在组件之间创建通信
我们有一个图标组件:

<Badge count={12} />
您在各种应用程序中看到了它们,它们将对象的数量显示为数字。

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

<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
。

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

<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(关于其道具)有好有坏

<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
称为,这是我能想到的最常见的名称-比标签,文本或值更笼统。

<Badge content="12" appearance="information" /> <Label content="private" appearance="information" />
我们丢失了一些细节,但保持了很多一致性。 我们仍然可以使用prop-types设置值类型 ,所以我认为这是一个很好的折衷方案。
但是,等等,在React中已经有了一个多功能的content
道具,它被称为children
-一个子代。
不要重props.children.
如果您已经定义了接受不基于数据结构的任意数据的道具,那么最好使用组合- 布伦特·杰克逊
这是本文的技巧- 在构图和道具之间进行选择时,请选择构图 。
让我们用children
,children重构这个API:

<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选项。
不难猜测,我喜欢第一个。
- 您无需考虑使用什么道具-
text
被称为? label
? 这些只是children
。 - 您可以根据需要添加
className
或target
。 对于第二个选项,您需要确保它支持这些属性或将它们简单地传递给基本元素。 - 这使您可以将子级包装在上下文中或更高级别的组件中。
规则的例外:
如果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
组件。
您是否注意到此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
,可以接受任何道具的组件。