react button 加颜色_编写有弹性的react组件

本文介绍了React组件设计中的四个重要原则:不阻断数据流,时刻准备渲染,没有单例组件,隔离本地状态。文章强调了避免在组件中复制props到state,确保side effects响应props的变化,以及正确处理组件渲染的时机。同时,提倡组件设计应具有弹性,能够适应更多场景和变化,避免过于依赖特定的渲染时序。
摘要由CSDN通过智能技术生成

当大家开始学习 React 时,常常问到风格指南。虽然呢,项目中应用一致的规则,是个不错的主意,但是很多规则挺随意的——所以 React 对这些并没有强烈的意见。

你可以使用不同的类型系统,使用函数声明或者箭头函数,也可以对你的属性按字母序或任何你愿意的其他顺序来排序。

这样的灵活性允许在项目中 整合 React 时,能应用已有的一些约定习惯。不过同时,这也会引发无休止的争论。

一些每个组件都应极力遵守的设计原则。但我不认为风格指南能很好地捕捉这些原则。接下来,我们先谈谈风格指南,然后再看看真的有用的设计原则。


别被虚幻的问题分散了注意力

在我们讨论组件的设计原则前,我想先简单说说风格指南。这不是个流行的观点,但有人得说出来!

在 JavaScript 社区中,有一些由 linter 强制约束的样式指南。我个人的观察是,他们会产生比他们价值更多的麻烦。我算不清有多少人向我展示过一些完全有效的代码,然后跟我说 “React 提示这有问题啊!”,但这其实是由他们的 lint 配置产生的!这就导致了三个问题:

  • 人们习惯于将 linter 看作是一个过分热心又吵闹的看门人,而不是一个有用的工具。 有用的警告被风格提示的海洋淹没了。因此,人们在调试时不看 linter 的提示,错过有用的信息。此外,之前不太写 JavaScript 的人群(例如,设计人员)也因此更难使用代码。
  • 对于某种模式,大家不太学着区分有效和无效的用法。例如,有一条流行的规则是,禁止在 componentDidMount 中调用 setState。但如果这个用法总是 “错的”,那 React 根本不会允许它!这就有一个合法的用例,那就是测量 DOM 节点布局——例如,定位 tooltip。我见过有人添加 setTimeout 来 “解决” 这条规则,这完全搞错了。
  • 最终,人们采用 “执法者心态”,对那些没带来有意义变化但在代码中易于发现的地方持批评态度。“你用了函数声明,但我们的项目用的是箭头函数。” 每次我有强烈意愿,想要强制执行类似的规则时,仔细想想就会发现,我把个人情绪投入到了这个规则中——然后又努力让这消失。这让我陷入虚假的成就感,而丝毫没有改进我的代码。

我这是在宣扬停止使用 linter 吗? 不!

通过良好的配置,linter 是一个很好的工具,它可以在 bug 出现前就能发现它们。但它对代码风格的关注过多,使其变得会分散注意力。


整理你的 Lint 配置

这是我建议你在周一要做的事。把你的团队叫到一起花半个小时时间,一条条过一下你们项目中启用的 lint 规则,接着问问自己:“这条规则有帮我找到过 bug 吗?” 如果不是,关掉这条规则。(你也可以用 eslint-config-react-app 从头开始创建,里面不含任何代码风格的规则)

至少,你的团队应该有一个流程,会去删除引起干扰的规则项。不要假设一年前你或别人添加到你的 lint 配置中的任何东西,都是“最佳实践”。保持质疑,找到答案。别让任何人告诉你,你不够聪明,不能选择 lint 规则。

那代码格式化呢? 用 Prettier 然后忘掉 “风格”。你完全不需要一个工具告诉你得在这加一个空格,如果有别的工具能为你修复它。用 linter 找 bug,而不是做 代 码 美 学

当然,某些方面来说,编码风格和格式没有直接关系,但在整个项目中存在不一致时还是很恼人。

然而,它们中的许多都太微妙了,无法通过一条 lint 规则捕捉到。这就是为什么说,在团队成员之间建立信任,在 wiki 或简短的设计指南里分享有用的知识,是非常重要的事了。

不是一切都值得自动化!从 实际阅读 中获得的见解,这种指南中的理由可能比遵循 “规则” 更有价值。

如果遵循严格的风格指南是一种分心,那到底什么才是重要的呢?

这就是这篇文章的主题。


编写有弹性的组件

不论多少缩进或按字母序排列,都不能修复糟糕的设计。因此,我不会专注于某些代码看起来如何,而是专注于如何让它工作。这有一些组件设计原则我认为是非常有用:

  1. 不阻断数据流
  2. 时刻准备渲染
  3. 没有单例组件
  4. 隔离本地状态

即使你不使用 React,对于存在单向数据流的任何 UI 组件模型,可能也能通过反复试验发现相同的原则。


原则 1:不阻断数据流

渲染中不要阻断数据流

当别人使用你的组件时,他们的预期是,不论传递属性如何变化, 组件都将反映这些变化:

// isOk 也许在 state 里,随时会变化 <Button color={isOk ? 'blue' : 'red'} />

通常,这是 React 默认工作的方式。如果你在 Button 组件中使用 color,你会看到从上层为该渲染提供的值:

function Button({ color, children }) { return ( // ✅ `color` 永远是新的 <button className={'Button-' + color}> {children} </button> ); }

然而,学习 React 时常见的一个错误是,把 props 复制到 state:

class Button extends React.Component { state = { color: this.props.color }; render() { const { color } = this.state; // `color` 不更新了! return ( <button className={'Button-' + color}> {this.props.children} </button> ); } }

这也许看起来更直观,如果你使用过 React 之外的东西。 但是,通过将 prop 复制到 state,你忽略了对它的所有更新。

// 上面的实现在更新时无法正常工作了 <Button color={isOk ? 'blue' : 'red'} />

很少情况下,这样的行为 有意为之的,请确认将这样的属性取名为 initialColordefaultColor 来表明组件会忽略这个属性的改变。

但通常你会想在你的组件中 直接读取 props,避免复制 props(或从 props 中计算得到的值) 到 state:

function Button({ color, children }) { return ( // ✅ `color` 永远是新的! <button className={'Button-' + color}> {children} </button> ); }


计算值是另一个大家可能会将 props 复制到 state 的场景。举例来说,想象一下 按钮文字 的颜色是根据 color 属性通过昂贵计算得来:

class Button extends React.Component { state = { textColor: slowlyCalculateTextColor(this.props.color) }; render() { return ( <button className={ 'Button-' + this.props.color + ' Button-text-' + this.state.textColor // `

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值