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

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

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

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

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

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

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

让我们谈谈Avatar组件。


头像1


 <Avatar image="simons-cat.png" /> 

化身在应用程序中随处可见,通常大小不同。 用户配置文件需要一个大头像,下拉列表中需要一个小头像,中间还有几个。


github头像


让我们添加道具sizesize道具)。


我们不想给开发人员指定任意宽度和高度的能力;相反,我们想给开发人员几个可能的尺寸。


头像2


 <Avatar size="xsmall" image="simons-cat.png" /> <Avatar size="small" image="simons-cat.png" /> <Avatar size="medium" image="simons-cat.png" /> <Avatar size="large" image="simons-cat.png" /> <Avatar size="xlarge" image="simons-cat.png" /> 

cosmos中 ,我们仍然有应用程序的化身。 我们希望它们看起来有些不同-圆角正方形而不是圆形。


创建良好的API的一部分是使开发人员能够考虑数据而不是设计-设计应该已经在组件中

我们可以添加另一个区分两种化身的道具。 一个小道具不会伤害,对不对?


头像3


 <Avatar type="user" image="simons-cat.png" /> <Avatar type="app" image="firebase.png" /> 

看起来不错,不是吗?


是的,我们获得了对应用程序头像的多种支持,因为它是相同的组件。 总的来说,我们不需要这个,但为什么不这样做,因为它没有花我们任何钱


头像4


 <Avatar type="app" size="xsmall" image="firebase.png" /> <Avatar type="app" size="small" image="firebase.png" /> <Avatar type="app" size="medium" image="firebase.png" /> <Avatar type="app" size="large" image="firebase.png" /> <Avatar type="app" size="xlarge" image="firebase.png" /> 

让我们谈谈开发人员将如何在其应用程序中实际使用此组件。 用户信息可能来自API,并且包含化身的URL。 开发人员将使用道具将此信息传递给Avatar组件。


如果用户尚未上传头像,我们想显示默认值,应用程序徽标也是如此。


头像6


 <Avatar type="user" image={props.user.avatar} /> <Avatar type="user" image={missing} /> <Avatar type="app" image={props.app.logo} /> <Avatar type="app" image={missing} /> 

默认图像已包含在组件中,因此我们不要求开发人员提供默认图像。


这是一个很好的后备,但我们可以做更多。


我们可以显示具有唯一背景的用户名的缩写(Gmail使此模板流行,它有助于快速区分人)


头像7


 <Avatar type="user" image={props.user.avatar} /> <Avatar type="user" image={missing} /> <Avatar type="user" initials={props.user.intials} image={missing} /> <Avatar type="app" image={props.app.logo} /> <Avatar type="app" image={missing} /> <Avatar type="app" icon={props.app.type} image={missing} /> 

让我们看一下组件支持的所有道具:


说明类型预设值
image图片网址string--
size头像大小string: [xsmall, small, medium, large, xlarge]small
type头像类型string: [user, app]user
initials用户缩写作为后备string--
icon图标显示为后备string: [list of icons]--

我们从一个简单的头像组件开始,但是现在它支持所有这些道具和行为!


当您看到支持许多道具的组件时,它可能正在尝试做太多事情。 您刚刚创建了Apropcalypse


Jenn Creighton提出了这个概念。


我们正在努力使Avatar组件可为用户和应用程序使用,同时为不同的后备行为使用不同的大小和不同的选项。


它还允许使用不推荐使用的奇怪组合,例如备用文本应用程序头像。 请记住,这是技巧1- 不要创建冲突的道具 (请参阅为React组件编写API,第1部分:不要创建冲突的道具 )!


好吧,我们该如何处理? 创建两个不同的组件。


提示:


不要害怕创建一个新组件,而不是向现有组件添加道具和其他逻辑。

首先,这是两个不同的头像组件的API外观:


头像7


 <UserAvatar size="large" image="simons-cat.png" /> <UserAvatar size="large" image="" /> <UserAvatar size="large" fallback="LA" image="" /> <AppAvatar image="firebase.png" /> <AppAvatar image="" /> <AppAvatar fallback="database" image="" /> 

此API中有几件事值得注意:


  1. 我们能够删除AppAvatar中不必要的功能,例如size
  2. 我们通过为两个组件保留相同的fallback名称(fallback)来减小API的大小
    还记得本系列的技巧2吗? 我们希望开发人员考虑行为( fallback ),而不考虑交互/实现(缩写或图标) 。 这有助于开发人员更快地学习API和使用组件的方式。
  3. 我们还可以避免任何冲突的道具
  4. 最后,我们减少了道具的数量。 看一下道具表,它变得更加干净:

UserAvatar:


说明类型预设值
image图片网址string--
size头像大小string: [xsmall, small, medium, large, xlarge]small
fallback用户缩写作为后备string--

AppAvatar:


说明类型预设值
image图片网址string--
fallback图标作为后备string: [list of icons]--

令我烦恼的是,尽管这两个组件的fallback: string名称和类型相同,但它们的名称和类型相同fallback: stringfallback: string类型的fallback: string是字符串),其中之一的首字母取两个字母,而时间与图标的名称相同。




让我们谈谈实现。 试图创建同时使用UserAvatarAppAvatarBaseAvatar组件很诱人,而某些道具将被阻止。


 function UserAvatar(props) { return ( <BaseAvatar image={props.image} type="user" initials={props.fallback} /> ) } render(<UserAvatar fallback="LA" />) 

这根本不是一个坏主意。 但是从一开始就很难预测我们可能需要什么。 我们很难预测未来的需求。


从两个不同的组件开始,并且在开发它们时,您可以开始看到相似的模式并找到一个好的抽象。 缺少抽象比不正确的抽象要好得多。


复制比不正确的抽象要好-Sandi Metz

回到您的代码,找到需要太多道具的组件,看看是否可以通过将其分成几个组件来简化它。




进一步研究:


  1. 珍妮·克雷顿(Jenn Creighton)的演讲 ,她在那儿谈论阿波罗卡利普斯
  2. Sandi Metz关于重复和抽象的演讲

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


All Articles