我研究了一下,看看能不能直接在 React 组件中直接使用 class,而不是 className,这样我的代码演示不就对味儿了吗?这一次,折腾了一会儿,我还真研究出来了!

React 有一个我忍了很久的痛点。如果有一天,我决定放弃 React 转向其他的框架,那么一定是这个痛点我终于忍不了了。
这个痛点就是 className。
<div className='relative pt-16'></div>
特别是最近我正在写一本关于 CSS 的专栏时,这个痛点已经把我逼到了几乎忍受不了的程度。

由于我的网站里,为了确保一致性、真实性、有效性,文章里的案例全部都是直接使用的内嵌案例的真实代码,但是网站是用 React 来写的,因此能够直接运行的代码也是 React 组件,展示出来的也就是 React 的代码。
但是这本专栏是专门介绍 CSS 的,如果代码中展示出来的是使用的 className,反正我不知道其他人是什么感受,我是越看越别扭,总感觉哪哪哪都不对劲。
所以我就想要研究一下,看看能不能直接在 React 组件中直接使用 class,而不是 className,这样我的代码演示不就对味儿了吗?
这一次,折腾了一会儿,我还真研究出来了!复制
export default function Page() {
return (
<div class='relative pt-16'>
<div class="fixed inset-0 -z-10">
<div class="absolute inset-0 bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:40px_40px]"></div>
</div>
...
</div>
)
}
我们先来了解一下 className 的历史原因,以及使用 class 之后可能会存在的问题,最后再给大家介绍具体如何操作。
1.历史原因
className 在 React 社区中争议了很多年,但是在设计之初,据说是为了在 token 层面,与声明类的关键字 class 区分开来,因此选择了重命名为 className。
class MyComponent extends Component {
// ...
}
不过除此之外,dan 在 github 中有提过另外一个理由。如下所示,在 JavaScript 中,给 DOM 设置属性有两种方式,一种是 property,另外一种 attribute。
node.value = 10; // setting a property
node.setAttribute('value', '10'); // setting an attribute
而 JSX 由于被约定为是 JS 语法的扩展,因此,React 团队认为使用 JS 默认的 className 字段给 DOM 设置属性比较合适。
node.className = '' // 表现为 property,而非 attribute
2.争议
尽管 dan 为此解释了很多次,但许多 React 开发者并不为此买账,在社区中强烈要求能够在 JSX 中使用 class
并且在后续的更新中,提议将 className 修改为 class 的声音越来越大。
React 团队为此不得不做出了妥协。
因此,在 React 17/18 的版本中,其实我们就可以直接在 JSX 中使用 class 了。但是他们又没完全妥协,选择的方式是,你可以用,代码也能正常运行,但是 React 会给你报错 ~ 就很恶心
dan 的解释是,
如果 React 团队毫无预警的同时支持 class 与 className,会在 React 生态中造成巨大的分歧。并不是所有的三方库都会同时兼容这两个方案,如果你使用的某一个三方库不兼容 class,那么就会导致样式的传递中断,出现问题。
React 团队无法完全左右社区,对于这种冲突无能为力,因此,长期以来,class 仍然以预警的方式存在。
但是,忍了 7 年了,我已经忍不了了,我决定不管要付出什么样的代价,必须要用 class,哪怕最后放弃使用 react。
那为了使用 class,我们要做什么额外的事儿呢?
3.弊端以及如何解决
在这之前,我们要明确,React 中,是支持直接使用 class 的。因此从功能的角度上而言,我们啥也不需要做,直接用就可以了。
但是当你直接使用之后,你会遇到一堆麻烦事儿需要解决。
首先,如果你的项目中使用了 TypeScript,他会疯狂报错,为了解决这个问题,我们要去修改 TypeScript 的类型声明。
在 @types/react 这个库中,我们在 HTMLAttributes 这个类型下面新增 class 字段。
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
...
className?: string | undefined;
class?: string | undefined;
...
}
处理好之后就搞定了。不过手动修改有一个比较麻烦的地方,就是每次你重新 install 之后,这段代码就会被覆盖,又还原成之前的样子。那么这个时候你有两个选择,
第一,由于修改起来比较简单,而且 install 频率也非常低,因此你可以每次都手动修改一下。
第二,你在 install 时执行一个本地脚本,用 node 代码自动去插入这段逻辑。
接下来的一个问题就是 eslint 等语法检测规则可能会报错,我们可以修改 ESLint 配置文件以消除这个错误。
"react/no-unknown-property": ["off"]
然后就是在开发环境中,console 面板里会报错,如下所示:

为了解决这个问题,我们需要在项目入口处,重写 console.error 的报错规则,具体代码我也已经研究出来了,分享给大家。
const originalError = console.error;
console.error = function(...args) {
const ignorePatterns = [
'Invalid DOM property `%s`. Did you mean `%s`?',
'class',
'className'
];
let shouldIgnore = true;
ignorePatterns.forEach((pattern, index) => {
if (typeof args[index] !== 'string' || !args[index].includes(pattern)) {
shouldIgnore = false;
}
});
if (!shouldIgnore) {
originalError.apply(console, args);
}
};
这段代码仅会消除 class 的报错,而不影响其他。
到这里,基本上所有的报错都解决掉了。
当我在群里和朋友圈分享这个的时候,有朋友问我是不是引入了什么三方工具或者插件,或者会不会影响编译结果,现在大家知道了,我没有用任何三方工具,只是修改了一些无关痛痒的报错提示。
并且,对于代码执行、编译不会有任何影响。
最后一个问题,如果你正在开发底层组件库,并且决定支持 className 的传入时,这里还会遇到一个新的问题。一个就是你需要同时支持 class 的传入,并且,当你使用结构时,必须对 class 进行重命名
const { class: cls } = props;
这个小的细节是 React 团队所担心的,会引起社区分歧的核心原因。但是如果是个人项目,你可以完全把控你的代码细节,那么这个分歧对于个人来说并不会有太大的影响。
4.总结
这是一个个人偏好的操作,我并不推荐大家像我一样使用。如果你也跟我一样讨厌 className,并且决定在项目中使用 class,可以参考一下我的做法,我基本上把潜在的隐患都考虑到了,放心使用是没问题的。
AI大模型学习福利
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
四、AI大模型商业化落地方案

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量
React中使用class替代className的方法

被折叠的 条评论
为什么被折叠?



