尽管使用React构建应用程序的许多方面已经进行了某种程度的标准化,但是样式是仍然存在许多竞争选择的领域。 每个人都有其优点和缺点,没有明确的最佳选择。
在本文中,我将简要概述Web应用程序样式在React组件方面的发展。 我还将简要介绍styled-components 。
JavaScript样式的演变
CSS的最初版本是在1996年,此后没有太大变化。 在第三个主要版本中,以及第四个主要版本中,它通过添加新功能而继续增长,并保持了其作为基本Web技术的声誉。 CSS始终是样式Web组件的黄金标准,但是它的使用方式每天都在变化。
从我们可以从分割的图像构建网站的时代到定制的手工滚动CSS可以反映图像的时代,随着JavaScript和网络作为平台的发展,CSS实现的发展也不断发展。
自从React在2013年发布以来,组件构建的Web应用程序已成为常态。 反过来,CSS的实现受到质疑。 反对将CSS与React内联使用的主要论点是关注点分离(SoC)。 SoC是一种设计原理,它描述了将程序划分为几个部分,每个部分解决了不同的问题。 当开发人员将三种主要的Web技术保存在单独的文件中时,便会使用此原理:样式(CSS),标记(HTML)和逻辑(JavaScript)。
这随着React中JSX的引入而改变。 开发团队认为,我们一直在做的实际上是技术的分离,而不是关注点 。 有人会问,既然JSX将标记移到了JavaScript代码中,为什么样式应该分开?
与离婚的样式和逻辑相反,可以使用不同的方法将它们串联在一起。 下面是一个示例:
<button style="background: red; border-radius: 8px; color: white;">Click Me</button>
内联样式会将CSS定义从CSS文件中移出。 因此,这消除了导入文件的需要并节省了带宽,但是却牺牲了可读性,可维护性和样式继承。
CSS模块
button.css
.button {
background: red;
border-radius: 8px;
color: white;
}
button.js
import styles from './button.css';
document.body.innerHTML = `<button class="${styles.button}">test</button>`;
从上面的代码示例中可以看到,CSS仍然驻留在自己的文件中。 但是,当CSS模块与Webpack或其他现代捆绑器捆绑在一起时,会将CSS作为脚本标签添加到HTML文件中。 还对类名进行了哈希处理,以提供更精细的样式,从而解决了级联样式表所带来的问题。
哈希处理涉及生成唯一的字符串而不是类名。 具有btn
的类名将导致DhtEg
的哈希,这将防止样式级联以及将样式应用于不需要的元素。
index.html
<style>
.DhtEg {
background: red;
border-radius: 8px;
color: white;
}
</style>
…
<button class="DhtEg">test</button>
从上面的示例中,我们可以看到CSS模块添加的样式标签元素,其中包含散列的类名和使用散列的DOM元素。
魅力
Glamor是一个CSS-in-JS库,允许我们在与JavaScript相同的文件中声明CSS。 再说一次,Glamour散列了类名,但是提供了一种干净的语法,可以通过JavaScript来构建CSS样式表。
样式定义是通过JavaScript变量构建的,该变量使用驼峰式语法描述了每个属性。 骆驼箱的使用很重要,因为CSS在火车箱中定义了所有属性。 主要区别在于属性名称的更改。 从应用程序或CSS示例的其他部分复制和粘贴CSS时,这可能是一个问题。 例如, overflow-y
将更改为overFlowY
。 但是,通过此语法更改,Glamour支持媒体查询和阴影元素,从而为我们的样式提供了更多功能:
button.js
import { css } from 'glamor';
const rules = css({
background: red;
borderRadius: 8px;
color: 'white';
});
const button = () => {
return <button {...rules}>Click Me</button>;
};
样式化的组件
styled-components是一个新的库,专注于将React组件和样式保持在一起。 提供了一个简洁易用的界面来对React和React Native进行样式化,样式化组件不仅改变了实现,而且正在改变构建样式化React组件的思维过程。
样式化的组件可以通过以下方式从npm安装:
npm install styled-components
作为任何标准npm包导入:
import styled from 'styled-components';
安装完成后,就该开始使样式化的React组件变得轻松愉快了。
构建通用样式的React组件
样式化的React组件可以通过多种方式构建。 样式组件库提供了使我们能够构建结构良好的UI应用程序的模式。 从小型UI组件(例如按钮,输入,排版和选项卡)进行构建,将创建一个更加统一和一致的应用程序。
使用之前的按钮示例,我们可以使用样式组件构建通用按钮:
const Button = styled.button`
background: red;
border-radius: 8px;
color: white;
`;
class Application extends React.Component {
render() {
return (
<Button>Click Me</Button>
)
}
}
如我们所见,我们能够创建通用按钮,同时使CSS与JavaScript保持一致。 样式化的组件提供了我们可以样式化的各种元素。 我们可以通过使用直接元素引用或将字符串传递给默认函数来实现。
const Button = styled.button`
background: red;
border-radius: 8px;
color: white;
`;
const Paragraph = styled.p`
background: green;
`;
const inputBg = 'yellow';
const Input = styled.input`
background: ${inputBg};
color: black;
`;
const Header = styled('h1')`
background: #65a9d7;
font-size: 26px;
`
class Application extends React.Component {
render() {
return (
<div>
<Button>Click Me</Button>
<Paragraph>Read ME</Paragraph>
<Input
placeholder="Type in me"
/>
<Header>I'm a H1</Header>
</div>
)
}
}
这种样式方法的主要优点是能够编写纯CSS。 从Glamor示例中可以看出,必须将CSS属性名称更改为驼峰式,因为它们是JavaScript对象的属性。
样式化组件还产生类似于现有元素的React友好基元。 利用JavaScript 模板文字 ,我们可以使用CSS的全部功能来设置组件样式。 如输入元素示例所示,我们可以定义外部JavaScript变量并将其应用于样式。
通过这些简单的组件,我们可以轻松地为我们的应用程序构建样式指南。 但是在许多情况下,我们还需要更复杂的组件,这些组件可以根据外部因素进行更改。
可定制的样式化React组件
样式组件的可定制性质是真正的优势。 通常可以将其应用于需要根据上下文更改样式的按钮。 在这种情况下,我们有两个按钮大小-小和大。 下面是纯CSS方法:
的CSS
button {
background: red;
border-radius: 8px;
color: white;
}
.small {
height: 40px;
width: 80px;
}
.medium {
height: 50px;
width: 100px;
}
.large {
height: 60px;
width: 120px;
}
的JavaScript
class Application extends React.Component {
render() {
return (
<div>
<button className="small">Click Me</button>
<button className="large">Click Me</button>
</div>
)
}
}
当我们使用样式化组件重现此样式时,我们将创建一个Button组件,该组件具有背景的基本默认样式。 由于组件的行为类似于React组件,因此我们可以使用props并相应地更改样式结果:
const Button = styled.button`
background: red;
border-radius: 8px;
color: white;
height: ${props => props.small ? 40 : 60}px;
width: ${props => props.small ? 60 : 120}px;
`;
class Application extends React.Component {
render() {
return (
<div>
<Button small>Click Me</Button>
<Button large>Click Me</Button>
</div>
)
}
}
高级用法
样式化的组件提供了创建复杂的高级组件的能力,并且我们可以使用现有的JavaScript模式来组成组件。 下面的示例演示了组件的组成方式-在通知消息的用例中,所有通知消息都遵循基本样式,但是每种类型都有不同的背景色。 我们可以构建一个基本的,样式化的组件,然后在顶部进行组合以创建高级组件:
const BasicNotification = styled.p`
background: lightblue;
padding: 5px;
margin: 5px;
color: black;
`;
const SuccessNotification = styled(BasicNotification)`
background: lightgreen;
`;
const ErrorNotification = styled(BasicNotification)`
background: lightcoral;
font-weight: bold;
`;
class Application extends React.Component {
render() {
return (
<div>
<BasicNotification>Basic Message</BasicNotification>
<SuccessNotification>Success Message</SuccessNotification>
<ErrorNotification>Error Message</ErrorNotification>
</div>
)
}
}
由于样式化组件允许我们传递标准DOM元素和其他组件,因此我们可以从基本组件组成高级功能。
组件结构
然后从高级示例开始,我们可以构建一个组件结构。 大多数标准的React应用程序都有一个components目录:我们将样式化的组件放置在styledComponents
目录中。 我们的styledComponents
目录包含所有基本组件和组成组件。 然后将它们导入到我们的应用程序使用的显示组件中。 目录布局如下所示:
src/
components/
addUser.js
styledComponents/
basicNotification.js
successNotification.js
errorNotification.js
结论
正如我们在这篇文章中所看到的,我们设计组件样式的方法差异很大-都不是一种明确的制胜法。 本文表明,样式化组件已经推动了样式元素的实现,并使我们对方法的思维过程提出了质疑。
每个开发人员,包括我自己,都有他们最喜欢的做事方式,并且很高兴知道根据我们正在开发的应用程序使用的不同方法的范围。 这些年来,样式系统和语言已经取得了长足的进步,毫无疑问,它们肯定会进一步发展并在未来进行更多更改。 在前端开发中,这是一个非常激动而有趣的时刻。
您首选的样式化React组件的方式是什么,为什么?
本文由Vildan Softic进行同行评审。 感谢所有SitePoint的同行评审人员使SitePoint内容达到最佳状态!
From: https://www.sitepoint.com/style-react-components-styled-components/