正确使用classnames库的方式摸索【玩转React】

举报
叶一一 发表于 2023/07/25 12:49:34 2023/07/25
【摘要】 前言我们日常开发使用的是React框架,主要采用JSX写法,而classnames与JSX十分般配,组合使用效果极佳,可以实现class的动态绑定。接下来,通过对 classnames 源码的阅读,来进一步了解classnames出现的契机及其用法。听说你叫 className讲 classnames 之前,科普一点关于它「兄弟」 className 的知识点。万物皆有源之 JSX众所周知,...

前言

我们日常开发使用的是React框架,主要采用JSX写法,而classnames与JSX十分般配,组合使用效果极佳,可以实现class的动态绑定。

接下来,通过对 classnames 源码的阅读,来进一步了解classnames出现的契机及其用法。

听说你叫 className

讲 classnames 之前,科普一点关于它「兄弟」 className 的知识点。

万物皆有源之 JSX

众所周知,在 Recat 中配合使用 JSX 语法。而 JSX 在语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称。

因此,在 React 中使用 className 为元素指定 CSS 的 class。

className 的两种用法

我们在 React 中是这样为元素添加样式的:

<div className="mt20">Hello World</div>

或者根据某个变量的值进行动态绑定,如下就根据 selected 的值判断是否为元素添加 active 样式:

<div className={`${selected ? 'active' : ''}`}>
  {selectedText}
</div>

必有但是

动态绑定的方式确实让代码变得更加灵活,但是上面这种 ES6 模板字符串的写法,当有多个判断的时,会显得臃肿且不好维护。

那,有没有更好的实现方案呢?

classnames 出现的契机

每当遇到一个新知识点,我总是不由的想,它为什么会诞生?它帮忙解决了什么问题?

开发者需要什么?

从前面的文字中提取关键讯息,不难发现,开发者需要更简洁绑定多个 className 的方式。

classnames 是什么?

classnames 源码的第一句介绍,正好符合开发者的需要

A simple JavaScript utility for conditionally joining classNames together.

直译过来就是

一个简单的、有条件的绑定多个 className 的 JavaScript 实用函数.

classnames 的用法

用前先安装

classnames 是一个第三方 JavaScript 库,使用前需要先安装。

npm、bower、yarn三件套

# via npm
npm install classnames

# via Bower
bower install classnames

# or Yarn (note that it will automatically save the package to your `dependencies` in `package.json`)
yarn add classnames

语法

classnames 函数支持多个传参,参数的类型也支持数值、字符串、对象、数组等多种

classnames(class1,class2,...classN)

用法很多样

基础用法

// 多个字符串 两种写法均可
classNames('mt10', 'font20') // => 'mt10 font20'
classNames('mt10 font20') // => 'mt10 font20'

//「字符串+对象」组合
classNames('switch', { selected: false }) // => 'switch'
classNames('switch', { selected: true }) // => 'switch selected'

// 对象 三种写法均可
classNames({ switch: true }, { selected: true }); // => 'switch selected'
classNames({ switch: true, selected: true }); // => 'switch selected'
classNames({ 'switch selected': true }); // => 'switch selected'

// 数组
classNames('font20', ['mt10', { switch: true, selected: false }]); // => 'font20 mt10 switch'

ES6 语法

支持动态类名

let type = 'disabled';
classNames('radio', { [`radio-${type}`]: true }); // => 'radio radio-disabled'
classNames('radio', `radio-${type}`); // => 'radio radio-disabled'

React 中使用

前面提到过 className 的知识点,React 中添加 class 使用 className

import classNames from 'classnames';

const checkboxCls = classNames('checkbox-group', { 'checkbox-group-horizontal': true });
<div className={checkboxCls}></div>

总结

先来总结一下classnames的用法:

  1. classnames 支持多种写法。
  2. classnames 函数的入参是无序的,但是编写习惯是字符串类型的放前面,其他放在后面。
  3. classnames 函数会忽略入参中的错误值。
  4. classnames 函数支持动态类名。

对「CSS-in-JS」的思考

现状

由于我们项目几乎都用的 React 框架,而 CSS-in-JS 写法是如此丝滑。在 CSS 中使用 JS 变量,在基础组件的建设中很有帮助。

思考

很多事物带有两面性,CSS-in-JS 在拥有写法灵活和支持局部作用域的优势的同时,会增加运行开销和包大小。

有点像「鱼与熊掌」做选择的感觉,目前还比较难抉择。

替代

我读到了一篇文章,是Emotion 的第二大活跃维护者 Sam 分享《我们为何弃用 css-in-js。这篇原文我没有办法打开,但是在掘金社区找到了译文,译文指路☞《为什么我们正在放弃 CSS-in-JS》

简单介绍一下这篇文章,文章前半部分介绍了 CSS-in-JS 的优缺点、复杂性。后半部分讲移除 CSS-in-JS 之后的新样式方案以及构建时 CSS-in-JS 方案看法。

带着这篇文章的结尾带来的启发,我开始考虑未来我们项目的改进方案。可能还需要多一些深入研究和局部实验之后才会有明确的答案。


作者:非职业「传道授业解惑」的开发者叶一一
简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。