如何在 React JS 中有条件地应用 CSS 类

Posted

技术标签:

【中文标题】如何在 React JS 中有条件地应用 CSS 类【英文标题】:How to conditionally apply CSS classes in React JS 【发布时间】:2017-01-09 21:34:31 【问题描述】:

我一直在思考如何最好地在 React JS 中有条件地应用 CSS 类。我看到了一些答案,但没有很多答案,或者它们没有我想要的那么详尽。

【问题讨论】:

你已经尝试过什么?条件是什么? React Js conditionally applying class attributes的可能重复 您好 Makyen,感谢您的回复。我之前一直在大量使用 Angular 1.x,自从开始使用 React 后,我​​想实现与 ng-class 相同的方法并有条件地应用类。我又玩了一些,并分享了我的发现。 【参考方案1】:

您可以简单地将类设置为状态,如下所示:

<div className= this.state.exampleIsTruthy ? 'yourClass' : '' >
  text
</div>

或者如果你想根据这样的状态切换类:

<div className= this.state.exampleTrueOrFalse ? 'shown' : 'hidden' >
  text
</div>

【讨论】:

简单起见A+ 您的第一个示例引发控制台错误:Warning: Received false for a non-boolean attribute className. 不幸的是,您需要使用三元,即使第二个值为空:this.state.exampleTrueOrFalse ? 'yourClass' : '' @Peadar 我已经更新了我的答案。前段时间自己得到了这个,但没想到要更新答案。谢谢✌? 如果条件为假,那么会添加一个空字符串的类名,并且类列表会包含一个双空格,对吧? @bytangle 可能是的。如果这是一个问题,也许返回 null 而不是 '' 会更好 ?【参考方案2】:

manipulating class names 上的 React 文档建议使用 classnames NPM 包。

软件包的文档很棒。

以下sn-p直接来自包READMEUsage section

classNames('foo', 'bar');                 // => 'foo bar'
classNames('foo',  bar: true );         // => 'foo bar'
classNames( 'foo-bar': true );          // => 'foo-bar'
classNames( 'foo-bar': false );         // => ''
classNames( foo: true ,  bar: true ); // => 'foo bar'
classNames( foo: false, bar: true );    // => 'bar'

// lots of arguments of various types
classNames('foo',  bar: true, duck: false , 'baz',  quux: true ); 
// => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1,  baz: null , ''); 
// => 'bar 1'

【讨论】:

【参考方案3】:

许多答案假设这是关于有条件地切换 CSS 类(三元 if 就足够了),但是当您需要选择性地包含类名时,这变得更加迟钝。带有空 false 表达式的多个三元 if 是冗长的。 NPM 包可能有点多。对于某些人来说,一个函数也可能是矫枉过正。

这就是我的工作。

const classNames = [
  "className1",
  condition1 && "className2",
  condition2 && "className3",
  condition3 && "className4",
].filter(e => e).join(" ");

自 2021 年 6 月起编辑

我注意到这个答案仍然偶尔会得到支持。想法 我将使用一个小而简洁的箭头函数提供一个稍微更新的示例:

const cls = (...classes) => classes.filter(Boolean).join(' ');

<div className=cls('mandatoryClass', condition && 'optionalClass') />

【讨论】:

嗨。我觉得你是个天才。也许您需要进一步开发您的示例,但它是完美的【参考方案4】:

如果您需要在现有类中添加条件类,这个可能会给您一个想法

<span className='fa ' + (this.state.dropdownActive ? 'fa-angle-up' : 'fa-angle-down')></span>

在此示例中,我根据下拉菜单的状态显示下拉菜单的箭头图标。我需要保留类fa 以设置跨度的字体系列,我只需要在fa-angle-upfa-angle-down 之间切换。

与模板文字相同的示例

<span className=`fa $this.state.dropdownActive ? 'fa-angle-up' : 'fa-angle-down'`></span>

【讨论】:

【参考方案5】:

使用类名库https://github.com/JedWatson/classnames

classNames 函数接受任意数量的参数,可以是 字符串或对象。如果 键的值是假的,它不会包含在输出中。

var classNames = require('classnames');

var Button = React.createClass(
  // ...
  render () 
    var btnClass = classNames(
      'btn': true,
      'btn-pressed': false,
      'btn-over': true
    );
    // output: btnClass = "btn btn-over"
    return <button className=btnClass>this.props.label</button>;
  
);

查看文档,如果您有任何问题,请告诉我!

干杯

【讨论】:

您能否对此进行扩展以使其可用【参考方案6】:

其他作者在上述评论中所述的解决方案对我有用

<div className= this.state.end ? 'hidden' : 'shown' >text</div>

如果您想添加更多类然后添加以空格分隔的类,只需添加一个。

【讨论】:

【参考方案7】:

作为记录,我认为classnames 库的答案是最正确的,但如果您不想引入另一个依赖项,您可以推出自己的简单实现,其工作原理类似于 jQuery:

function getClassBuilder () 
    return 
        array: [],
        add: function (className) 
            if (this.array.indexOf(className) < 0) 
                this.array.push(className);
            
        ,
        remove: function (className) 
            var index = this.array.indexOf(className);
            if (index > -1) 
                this.array.splice(index, 1);
            
        ,
        toString: function () 
            return this.array.join(' ');
        
    

那么,当你需要使用它时:

var builder = getClassBuilder();
builder.add('class1');
builder.add('class2');
if (condition)  builder.remove('class1') ;

<a href="#" className=builder.toString()>Button</a>

【讨论】:

类名库本身很小,你在这里重写了它。我建议坚持使用类名:github.com/JedWatson/classnames/blob/master/index.js 作为记录,我同意。我的帖子针对"not invented here" 人群。【参考方案8】:

我将在引导类上进行说明,将有条件地更改文本的颜色: 如果 count=0 文本为红色,否则为蓝色

class Counter extends Component 
  state =  count: 6 ;

  render() 
let classes="text-center" //class is reserved word in react.js
classes+= (this.state.count===0) ? "text-danger" : "text-primary"
    return (
      <div>
        <h2 className=classes>Hello World</h2>
      </div>
    );
  
  formatCount() 
    const  count  = this.state;
    return count === 0 ? "zero" : count;
  

【讨论】:

【参考方案9】:

具有静态类名的单一条件

<div className="container " + (this.props.condition === true ? 'show' : 'hidden')>

静态类名的双重条件

<div className="container " + (this.props.condition === true ? 'show ' : 'hidden ') + (this.props.secondCondition === true ? 'visible' : 'invisible')>

最后需要在条件类或静态类之间留出空间

【讨论】:

【参考方案10】:

好的,所以我一直在尝试,结果证明是有方法的,并没有我想象的那么难。 这可能会对刚开始使用 React JS 的人有所帮助。

所以有两种方法和添加内联样式的两个原因:

(1) 在样式属性中添加类名作为对象,以便可以在常规 CSS 样式表中、直接在 JSX 文件中或用于条件 CSS 中设置样式

示例 1

const classNameAsAPlainObject = 
        color: '#333333',
        backgroundColor: '#999999'


<a href="#" className="an-existing-class" style=classNameAsAPlainObject >
Button
</a>

示例 2

const conditionIsSomething = 
    color: 'red'

<a href="#" className="an-existing-class" style=conditionIsSomething ? 'classNameBasedOnCondition' : ' ' >
Button
</a>

在第二个例子中,可以声明两个不同的类,具体取决于 在期望的结果上,或者如果条件为真,则可以声明一个类 如果条件为假,则无。

(2) 将其添加到需要条件的常规 className 属性中,但请确保适应现有的类名称,并注意此方法需要在常规 CSS 文件中设置样式。如果不需要条件,则照常将类添加到 className 属性中。

示例 3

<a href="#" className="an-existing-class " + (conditionIsSomething ? 'thisClass' : 'thatClass')>
Button
</a>

示例 4

<a href="#" className="an-existing-class " + (conditionIsSomething ? 'aClassIsAdded' : ' ')>
Button
</a>

同样,如果条件需要,可以声明一个类或不声明 如示例 4 所示。在任何一种情况下,请务必在后面留一个空格 "an-existing-class" 和结束引号之前,所以有一个空格 对于条件类。

所以我想作为一般的经验法则,你添加一个类和样式作为一个对象(如示例 1 和 2),你可以在 JSX 文件中设置它的样式,但是如果将类名添加到“className”属性,您将在常规 CSS 文件中对其进行样式设置。我实际上没有尝试过这个,所以我会尝试一下。如果有人发现不是这样,请不吝赐教。

【讨论】:

这不是一个好习惯。类名库就是为此而设计的,它很小,并且使 JSX 具有高度可读性。 注意!感谢您的提醒

以上是关于如何在 React JS 中有条件地应用 CSS 类的主要内容,如果未能解决你的问题,请参考以下文章

在 React.js 中有条件地设置 html 属性

如何有条件地渲染我的 CSS 类的一部分

React-有条件地在 div 中应用 css 但它不起作用

如何在反应中有条件地添加样式? [复制]

如何在 sequelize.js 中有条件地加载关联?

如何在created()或mounted()中有条件地呈现JS