简体   繁体   English

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

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

I've been musing on how best to conditionally apply a CSS class in React JS.我一直在思考如何最好地在 React JS 中有条件地应用 CSS 类。 I've seen some answers banding around but there aren't many out there or they're just not as elaborative as I'd like.我已经看到了一些答案,但没有多少答案,或者它们没有我想要的那么详尽。

You can simply condition class to state, like this:您可以简单地将类设置为状态,如下所示:

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

or if you want to switch classes based on a state like this:或者如果你想根据这样的状态切换类:

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

The React documentation on manipulating class names suggests the classnames NPM package.关于操作类名的 React 文档建议使用classnames NPM 包。

The docs for the package are great.该软件包的文档很棒。

The following snippet is straight from the package README : Usage section以下代码段直接来自包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'

Many answers assume this is about conditionally toggling CSS classes ( ternary if is adequate), but this become far more obtuse when you need to optionally include classnames.许多答案都假设这是关于有条件地切换 CSS 类(如果足够,则为三元),但是当您需要选择性地包含类名时,这变得更加迟钝。 Multiple ternary ifs with empty false expressions is verbose.带有空假表达式的多个三元 if 是冗长的。 An NPM package may be a tad much. NPM 包可能有点多。 A function too may be overkill for some.对于某些人来说,一个函数也可能是矫枉过正。

Here's what I do.这就是我所做的。

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

Edit as of June 2021截至 2021 年 6 月编辑

I'm noticing this answer still sees the occasional upvote.我注意到这个答案仍然偶尔会看到赞成票。 Thought I'd provide a slightly updated example using a small and succinct arrow function:我想我会使用一个小而简洁的箭头函数提供一个稍微更新的例子:

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

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

If you need to add a conditional class to an existing class, this one may give you an idea如果您需要在现有类中添加条件类,这个可能会给您一个想法

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

in this example, I am showing an arrow icon for a dropdown depending on the state of the dropdown.在这个例子中,我根据下拉菜单的状态显示了下拉菜单的箭头图标。 I need to keep the class fa for any case to set the font-family of the span, and I only need to switch between fa-angle-up and fa-angle-down .在任何情况下,我都需要保留类fa来设置跨度的字体系列,我只需要在fa-angle-upfa-angle-down之间切换。

Same example with template literals与模板文字相同的示例

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

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

The classNames function takes any number of arguments which can be a string or object. classNames 函数接受任意数量的参数,这些参数可以是字符串或对象。 If the value of the key is falsy, it won't be included in the output.如果键的值是假的,它将不会包含在输出中。

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>;
  }
});

Take a look at the doc and let me know if you have any questions!看看文档,如果您有任何问题,请告诉我!

Cheers干杯

The solution which is stated below by other author in above comment works for me其他作者在上述评论中陈述的解决方案对我有用

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

Just a add on if you want to add more classes then add class separated by space.如果您想添加更多类,只需添加一个,然后添加以空格分隔的类。

For the record I think the classnames library answers are the most correct, but if you didn't want to pull in another dependency, you could roll your own simple implementation that works kind of like jQuery:作为记录,我认为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(' ');
        }
    }
}

then, when you need to use it:然后,当您需要使用它时:

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

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

I will illustrate on bootstrap classes, will change the color of the text conditionally: If count=0 text will be red, otherwise will be blue我将在 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;
  }
}

Single Condition with Static ClassName具有静态类名的单一条件

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

Double Condition with Static ClassName静态类名的双重条件

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

need to give space between conditional class or static class by the end最后需要在条件类或静态类之间留出空间

Ok, so I've been experimenting and it turns out there are ways and it's not as hard as I thought.好的,所以我一直在试验,结果证明有很多方法,而且并不像我想象的那么难。 This might help those just starting out in React JS.这可能会帮助那些刚开始使用 React JS 的人。

So there are two ways of doing so and two reasons for adding in-line styles:所以有两种方法和两个添加内嵌样式的原因:

(1) Add class name inside a style attribute as an object so it can be styled inside a regular CSS stylesheet, directly inside a JSX file or used for conditional CSS (1) 在样式属性中添加类名作为对象,以便可以在常规 CSS 样式表中、直接在 JSX 文件中设置样式或用于条件 CSS

EXAMPLE 1例 1

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

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

EXAMPLE 2例2

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

In the second example, two different classes can be declared depending on desired result or one class can be declared if condition is true or none if condition is false.在第二个示例中,可以根据所需的结果声明两个不同的类,或者如果条件为真则声明一个类,如果条件为假则可以声明一个类。

(2) Add it to the regular className attribute where a condition is required but be sure to accommodate for existing class names and be aware that this method requires styling in a regular CSS file. (2) 将它添加到需要条件的常规 className 属性中,但一定要适应现有的类名,并注意此方法需要在常规 CSS 文件中设置样式。 If no condition is required, then add the class as per normal to a className attribute.如果不需要条件,则按照正常方式将类添加到 className 属性。

EXAMPLE 3例3

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

EXAMPLE 4例4

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

Again, if the condition requires it, one class can be declared or none as seen in example 4. Be sure to leave a space in either case after the "an-existing-class" and before the closing quote so there's a space for the conditional class.同样,如果条件需要,则可以声明一个类或不声明一个类,如示例 4 所示。确保在任何一种情况下都在“an-existing-class”之后和结束引号之前留一个空格,以便有一个空格用于条件类。

So I guess as a general rule of thumb, you're adding a class and styling as an object (as with Example 1 and 2), you can style it within the JSX file, but if adding a class name to the "className" attribute, you will be styling it inside a regular CSS file.所以我想作为一般的经验法则,您将类和样式添加为对象(与示例 1 和 2 一样),您可以在 JSX 文件中对其进行样式设置,但是如果将类名添加到“className”属性,您将在常规 CSS 文件中对其进行样式设置。 I haven't experimented with this actually so I will give that a try.我还没有真正尝试过这个,所以我会尝试一下。 If anyone finds otherwise, please enlighten me.如果有人发现其他情况,请赐教。

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

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