阅读 1798

React项目使用styled-components后的几点感受

最近在项目里使用了 styled-components 来写 CSS,感觉有一些好处,但也遇到了一些问题,本文简单记录一下这一个多月的使用感受。

首先,简单介绍一下 styled-components,它是一种 CSS-in-JS 的实现,它官网的介绍是:

Utilising tagged template literals (a recent addition to JavaScript) and the power of CSS, styled-components allows you to write actual CSS code to style your components. It also removes the mapping between components and styles – using components as a low-level styling construct could not be easier!

简而言之,它是利用 ES6 的 tagged template literals 创建 React 纯样式组件。

简单看一个例子:

import styled from 'styled-components'

const Button = styled.button`
  color: red;
`
复制代码

这里的 styled.button`` 语法其实就是一个 tagged template literals,它实际上相当于调用了一个 button 函数。得到的 Button 组件和其他的一般的 React 组件的用法是一样的:

<Button>Click Me!</Button>
复制代码

这一段时间使用下来,感觉是 styled-components 还是很容易上手的,学习曲线很平缓,它还有以下一些优点。

好的方面

1. 没有想样式名的烦恼了

不用再想每个样式对应的 className 了,有 JSX 组件名就行,消除了开发人员想合适的 className 的烦恼。而且,它会生成全局唯一类名,不用担心冲突。

image.png

可以看到,我们不用为 DOM 元素定义 className 了,只需要想一个语义化的组件名就好了。

3. 很容易找到组件对应的样式代码

因为用 styled-components 定义的组件是一个 JS 变量,可以很容易的在定义和使用的地方之间相互跳转,用起来很方便。

即使引用了一些定义在别的文件的公共组件(比如 Typography 字体),也能很快跳转过去。

不会像以前一样,如果样式文件很大以后,需要通过搜索 className 才能找到相应的样式。

4. 不会有没用到的样式代码

以前用 SASS/LESS 之类的库时,因为代码结构的调整很容易造成一些嵌套的样式代码最终变成 dead code,尤其是大项目里修改别人的代码很容易出现这类问题。

使用了 styled-components 之后,如果项目中用了 Typescript,并且启用了 no-unused-vars 检查,那么我们就能保证项目里不会因为改来改去造成没有用到的样式代码。

image.png

下面再来列举一下目前使用下来感觉 styled-components 一些不太好的地方。

不太好的方面

1. 生成的 className 是随机字符串,不方便 debug

image.png

上文说了 styled-components 的一大好处就是不用我们想 className 了,但是这样也带来了一个麻烦,就是它自动生成的 className 都是一些随机字符串,在浏览器 console 里很不方便调试。

不过可以安装 babel-plugin-styled-components 解决这个问题。

设置好后,就可以在浏览器里看到可读的class名,像这样:

<div class="Title-gvPLgb">...</div>
复制代码

2. createGlobalStyle 里引用字体文件造成每次重新渲染都需要重新下载字体文件

之前项目里遇到了一个很奇怪的 bug,在一个输入框里打字的时候,输入框上面 label 文字会闪烁。

最后才发现是因为我们在 styled-components 的 createGlobalStyle 里面用 @font-face 引用了自定义的字体文件,这会导致每一次页面刷新时字体文件都会重新下载,所以看到的就是文字从一种字体变为另一种字体,看起来就是闪烁了一下。

import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  @font-face {
    font-family: "MyFont";
    src: url("static/fonts/Std-Regular.otf");
  }
  @font-face {
    font-family: "MyFont";
    font-weight: bold;
    src: url("static/fonts/Std-Bold.otf");
  }
  @font-face {
    font-family: "MyFont";
    font-weight: 600;
    src: url("static/fonts/Std-SemiBold.otf");
  }
  
`;

export default GlobalStyle;
复制代码

最后我们的解决方案是,还是用普通 CSS 的方式(index.css)引入字体文件。

3. 默认没有 CSS 语法高亮和提示

用 styled-components 写 CSS 代码时,默认是没有语法高亮和提示的,这样写起来就会比较痛苦,而且即使有时候不小心写错了 CSS 属性名或属性值,它也不会报错,只是样式不生效而已。

image.png

比如上面这个例子里,width 就是不生效的,应该写成 10px,但是默认是不会报错的。

不过,这个问题可以通过一些插件解决,比如 intellij 里可以安装 Styled Components & Styled JSX 这个插件。

4. 重写组件样式不生效

刚开始用 styled-components 的人,很容易遇到重写样式不生效的问题,比如下面的例子,StyledLink 想要重写 Link 上的颜色和字体粗细,结果发现并不生效。

image.png

查了文档才发现,必须要把 className 传递给组件才生效(如果是 React Native 组件,需要把 style 传递下去)。

The styled method works perfectly on all of your own or any third-party component, as long as they attach the passed className prop to a DOM element.

image.png

总结

就我目前这短暂的使用经历来说,我自己还是比较喜欢用 styled-components 的,提高了一点儿我的开发效率。

文章分类
前端
文章标签