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

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

【问题讨论】:

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

标签: javascript css reactjs


【解决方案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>
        

        【讨论】:

        【解决方案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 具有高度可读性。
            • 注意!感谢您的提醒
            猜你喜欢
            • 2015-08-12
            • 1970-01-01
            • 1970-01-01
            • 2021-11-29
            • 1970-01-01
            • 2022-11-17
            • 1970-01-01
            • 2019-01-07
            • 2019-02-25
            相关资源
            最近更新 更多