让我们在 2019 年看看 React 中的 CSS - Styled Components
大家好!又到了用 React 来探索 JS 中 CSS 的酷炫时刻了。随着本系列的开始,我一直在思考如何以有趣且信息丰富的方式组织这些条目。我一直试图根据我的个人经验来编写;这一点不会改变,但我一直在纠结于应该深入到什么程度才能避免写出一份粗略的 React 文档。根据我在 React-JSS 条目评论中看到的一些内容,我将尝试更深入地探讨一下。
感谢所有观看本系列并留下精彩评论和反馈的朋友们。希望大家能继续留言,分享反馈、讨论和提问!你们太棒了!
什么是 Styled-Components?
按照往常一样,让我们真正了解这是什么的最好方法就是查看文档!
styled-components 是我们思考如何增强 CSS 来为 React 组件系统设计样式的结果。
我认为这个描述比解释更能起到推销的作用,所以我将尝试解开它,所以请耐心等待。
styled-components 允许您在我们的 React 组件中使用 CSS 描述您的样式。
这可能是我们在 JS 中最接近实际 CSS 的一次;至少对于 React 来说,让我们看一个简单的示例,使用我们方便的绿色按钮和内联样式作为基线进行比较。
内联样式
// Button.js
import React from 'react'
const Button = () => {
const buttonGreen = {
backgroundColor: "green",
border: "2px solid white",
borderRadius: "2rem"
};
return(
<button style={buttonGreen}>
I think I'm green
</button>
)
}
样式化组件
// Button.js
import React from 'react'
import styled from 'styled-components'
const ButtonGreen = styled.button`
background-color: green;
border: 2px solid white;
border-radius: 2rem;
`
const Button = () => {
return(
<ButtonGreen>I think I'm green</ButtonGreen>
)
}
实施情况有何变化?
- 我们
styled
从styled-components
包中导入。 - 我们
ButtonGreen
使用 定义了变量styled.button
。 - 我们
ButtonGreen
用 CSS 语法描述了我们的样式! - 我们在组件中使用它
ButtonGreen
作为组件根Button
。
在进一步讨论之前,我们先来稍微分析一下这里发生了什么。
定义ButtonGreen
变量时,我们确保使用帕斯卡命名法,而不是使用驼峰命名法。这是因为styled
我们定义的是一个要使用的组件,而不是将值传递给属性或 prop。.button
第 5 行的 是我们选择作为根元素的 HTML 元素ButtonGreen
,您可以使用此链中的任何 HTML 元素。此操作的结果将生成一个我们定义为根元素的 HTML 元素,其 className 经过哈希处理。
我们还来看看上次值得信赖的 Button 组件与影响我们样式的 props 之间的比较。
使用内联样式的 Props
// Button.js
import React from 'react'
const Button = ({backgroundColour, children}) => {
const buttonStyles = {
backgroundColor: backgroundColour,
border: "2px solid white",
borderRadius: "2rem"
};
return(
<button style={buttonStyles}>
{children}
</button>
)
}
将 Props 与 Styled Components 结合使用
// Button.js
import React from 'react'
import styled from 'styled-components'
const Button = styled.button`
background-color: ${props => props.backgroundColour};
border: 2px solid white;
border-radius: 2rem;
`
const Button = ({backgroundColour, children}) => {
return(
<Button backgroundColour={backgroundColour}>
{children}
</Button>
)
}
实施情况有何变化?
- 我们传递了一个名为“prop”的属性
backgroundColour
给我们的样式组件 - 我们
backgroundColour
在插值字符串中使用箭头函数引用了我们的 prop 值。
Phil 的精彩瞬间
这里还有很多功能可以提供;我不会一一介绍,因为文档就是专门讲解这些的,但我将介绍我最喜欢的功能。目前为止,我们所看到的一切都已经让我心动不已,因为一切都非常简洁,因为当你的组件变得庞大时,它们可能会变得难以阅读或保留其上下文。在我看来,Styled-Components 为我们提供了一个良好的基础,并且几乎不需要费力就能让事情变得更容易。
从组件扩展样式
到目前为止,我们已经了解了如何通过 props 控制组件的样式,从而创建具有不同样式的组件变体。赋予组件对特定 CSS 属性进行精细控制的能力固然很好,但在我看来,它确实存在一个相当混乱的缺陷。随着组件样式规则数量的增加,在组件用于功能的 props 之上,向特定样式规则添加更多 props 确实会变得越来越麻烦。
我们的按钮仅使用 props 的可能未来
// Button.js
import React from 'react'
import styled from 'styled-components'
const Button = styled.button`
background-color: ${({backgroundColour}) => backgroundColour};
border: ${({borderWidth}) => borderWidth } ${({borderStyle}) => borderStyle} ${({borderColour}) => borderColour};
border-radius: ${({borderRadius}) => borderRadius}$;
`
const Button = ({
backgroundColour,
borderWidth,
borderStyle,
borderColour,
borderRadius,
onClick,
children
}) => {
return(
<Button
backgroundColour={backgroundColour}
borderWidth={borderWidth}
borderStyle={borderStyle}
borderColour={borderColour}
borderRadius={borderRadius}
onClick={() => onClick()}
>
{children}
</Button>
)
}
我知道,除了实心边框之外,很少有人会用其他边框样式。我们这个最基本的按钮有很多属性,用来做各种功能,而且只会越来越大越来越吓人。在我看来,这最适合动态样式或特殊情况。
扩展按钮以进行变化
// SignUpButton.js
import React from 'react'
import styled from 'styled-components'
import Button from '../components/Button'
const SignUpButton = styled(Button)`
margin: 1rem;
border-radius: 4rem;
font-weight: bold;
color: #fff;
backgroundColour: "spring green";
`
// SomePage
import React from 'react'
import SignUpButton from '../components/SignUpButton'
const SomePage = () => (
<div>
...
<SignUpButton>Sign up now</SignUpButton>
...
</div>
)
这是我最喜欢的 styled API 功能之一。我们可以从 styledButton
组件扩展,创建一个变体,添加额外的样式或覆盖我们基于的现有样式;无需添加额外的 props 或类,从而避免应用程序出现我所说的“特异性复杂度”。我发现这非常适合将可重用的变体拆分到单独的文件中,或者在需要时应用一次性样式而不更改原始样式Button
。
将样式组件渲染为
如果我们想用不同的根 HTML 元素来渲染,Button
而不创建不同的组件或修改的Button
渲染,该怎么办?
我们可以通过每个 Styled 组件被调用的精彩道具来做到这一点as
将按钮渲染为锚点
// SomePage
import React from 'react'
import Button from '../components/Button'
const SomePage = () => (
<div>
...
<Button as="a" href="#LearnMore">Learn More</Button>
...
</div>
)
减去潜在的添加的道具href
,我们不需要对我们的Button
组件进行任何大规模的重构,并且仍然相当基本地满足其需求。
我个人喜欢 Styled Components 的哪些方面
我使用 Styled Components 已经有一段时间了,虽然这才刚开始,但我认为它可能是我最喜欢的 React 的 CSS in JS 解决方案。这也是我着手撰写这个系列的原因之一,因为我需要更多理由去看看还有什么其他方案;看看有没有比它更适合我的地方。
用 CSS 描述 CSS
对象样式抽象了一些内容,使其变得繁琐,所以能够直接使用常规的 CSS 语法真是太棒了。尤其是在将 CSS 规则转换为 styled-components 时,这尤其有用,因为大部分内容都是复制粘贴!关于这一点,其实没什么好说的了。
一切都是组件!
有了 styled API,你最终会得到更多根据上下文命名的 styled-components,我个人觉得这样更容易理解组件中正在发生的事情以及背后的原因。一切都更具声明性,更符合 React 的初衷。
我个人不喜欢 Styled Components 的哪些方面
混乱的 React 节点
如果你在 React Dev Tools 中查看组件视图,会发现你的 styled-components 中有一些复杂的上下文提供程序嵌套。我不确定这是否真的影响很大,也许会导致一些不必要的渲染。
然而,并不是要忽视这个不喜欢的点,而是在即将推出的版本中,5 正在修复这个问题,如果你安装 5 测试版,就可以检查出来。
我会使用样式化组件吗?
是的。这是我目前的首选。
大声呼喊情感
你们当中有些人读到这里可能已经对着屏幕尖叫,恨不得马上评论:“菲尔,情绪怎么办?” 情绪真是糟透了!
我是在开玩笑。
Emotion 是另一个 CSS in JS 解决方案,它提供了更丰富的 API。其中包括其 emotion/styled API,可以方便地与 styled-components API 兼容;它们既是死对头,又是好朋友。有了它,你几乎可以根据需要在这两个库之间切换,无需担心。
我没提 Emotion,这样就不用用到这两个库名了。我不会专门写 Emotion 的条目,因为我主要讲解的是相同的内容。
这标志着我之前使用过的库的记录到此结束,所以接下来的学习将会是全新的领域。如果你对接下来的学习内容有什么建议,请在评论区留言!
插头时间到了
我们已经开始播客了!
Keith Brewster 和 Phil Tietjen 是两位加拿大 Web 开发者,也是好朋友。他们决定创办一档名为“周五晚间部署”的播客节目,或许更贴切地描述为专注于 Web 开发、以人为本的播客节目。这档节目计划每周五播出,我们会分享彼此在相关主题上的经验和故事,以及我们日常生活中常做的事情。
在哪里收听
Spotify: https://open.spotify.com/show/7oXdJ5aETg5GBSNC6jZSNq
iTunes: https: //podcasts.apple.com/ca/podcast/friday-night-deploys/id1485252900
Google Play 音乐: https://play.google.com/music/m/I54hbbplhdmovo2so6cxsctkcaq ?t=
Friday_Night_Deploys PodBean: https: //devplebs.podbean.com/
如何联系我们
Twitter: https://twitter.com/DevPlebs(欢迎 DM 或提及)
电子邮件: devplebs@gmail.com
我们希望您能享受聆听的乐趣并期待收到您的回复!
文章来源:https://dev.to/phizzard/let-s-take-a-look-at-css-in-js-with-react-in-2019-styled-components-1olc