繁体   English   中英

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

[英]How to conditionally apply CSS classes in React JS

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

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

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

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

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

关于操作类名的 React 文档建议使用classnames NPM 包。

该软件包的文档很棒。

以下代码段直接来自包README用法部分

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'

许多答案都假设这是关于有条件地切换 CSS 类(如果足够,则为三元),但是当您需要选择性地包含类名时,这变得更加迟钝。 带有空假表达式的多个三元 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')} />

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

<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>

使用类名库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>;
  }
});

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

干杯

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

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

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

作为记录,我认为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>

我将在 bootstrap 类上进行说明,将有条件地更改文本的颜色:如果 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;
  }
}

具有静态类名的单一条件

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

静态类名的双重条件

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

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

好的,所以我一直在试验,结果证明有很多方法,而且并不像我想象的那么难。 这可能会帮助那些刚开始使用 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 文件中对其进行样式设置。 我还没有真正尝试过这个,所以我会尝试一下。 如果有人发现其他情况,请赐教。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM