我目前正在学习React和Redux。我已经分叉了一个样板,目前我正在查看所有代码以了解它是如何组合在一起的。
在扫描一些React Component文件时,我发现了一些非常有趣的东西!为许多元素设置className
时,它们使用的语法不同。他们第一次使用以下语法:
<span className={classes['counter--green']}>
...
</span>
然后这句法语:
<button className='btn btn-default'>
...
</button>
从那时起,他们使用以下内容:
<h2 className={classes.counterContainer}>
...
</h2>
在文件顶部,他们使用以下内容导入classes
:
import classes from './Counter.scss'
所以我的问题就是,为什么className有三种不同的语法,哪一种是正确的?
答案 0 :(得分:3)
从简单的案例开始:
<button className='btn btn-default'>
这只是将类名设置为"btn btn-default"
。您需要设置className
而不是class
,因为您正在编写JSX,这相当于设置className
DOM property,因此您必须在此使用className
。
<span className={classes['counter--green']}>
<h2 className={classes.counterContainer}>
这些都非常相似。在JSX中,要指定更复杂的JavaScript表达式,需要将其放在花括号中。这相当于设置className
属性,如下所示:
someSpan.className = classes['counter--green'];
someH2.className = classes.counterContainer;
最后,使用classes
语法导入的import classes from './Counter.scss'
是一个名为“CSS modules”的功能。它涉及一个预编译器步骤,可以在以后正确设置类名,并确保将样式定义呈现给HTML。
所以回答你的最后一个问题,所有这些都是正确的。您想要使用的内容取决于您要定义样式的位置(或定义它们的位置)。如果要创建甚至可能在其他地方重用的独立组件,那么使用CSS模块会很有意义。当你有一个你想要使用的现有样式表时,使用全局CSS是很好的(例如,这里,这些类名可能来自bootstrap)。当然,如果您有全局样式并希望为其添加其他样式,您也可以将它们混合使用。
答案 1 :(得分:2)
在这种情况下,在没有看到代码的情况下,我猜测样板文件正在使用模块化css(scss)。
可以导入模块化css,在本例中为 classes 。使用模块化css为您提供具有本地范围的css
从模块导入的所有css规则,因为类的前缀是名称类。
并在处理对象属性时予以对待
所以css rule counterContainer 用作
classes.counterContainer
css规则名称 counter-green 不能使用点表示法(因为连字符),所以必须使用方括号和字符串名称表示法作为任何javascript对象属性
classes['counter-green']
第三个示例 btn btn-default 不是从css类模块导入的,而是全局导入的。这可能是在根级别导入的bootstrap类,作为index.html
上的链接属性答案 2 :(得分:1)
这对于className来说并不是唯一的,但对于任何JSX,您都可以使用花括号{}
来切换&#34; JSX模式&#34;回到javascript使用任何JS表达式。因此,在第一个示例中,他们通过属性className
引用名为classes
的对象来设置属性counter--green
,在第二个示例中,他们使用简单的JSX字符串文字{{1}在第三个示例中,它们通过属性'btn btn-default'
引用classes
对象。您可以根据问题末尾的导入来查看classes对象的定义。
他们都是正确的,他们只是不同的方式。通过使用JS表达式,它们可以说是模块化的,通过使用字符串文字,可以更容易地在您面前看到正在发生的事情,但是可重用性较低。