React Js有条件地应用类属性


333

我想有条件地显示和隐藏此按钮组,具体取决于从父组件传入的内容,如下所示:

<TopicNav showBulkActions={this.__hasMultipleSelected} />

....

__hasMultipleSelected: function() {
  return false; //return true or false depending on data
}

....

var TopicNav = React.createClass({
render: function() {
return (
    <div className="row">
        <div className="col-lg-6">
            <div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">
                <button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
                  Bulk Actions <span className="caret"></span>
                </button>
                <ul className="dropdown-menu" role="menu">
                  <li><a href="#">Merge into New Session</a></li>
                  <li><a href="#">Add to Existing Session</a></li>
                  <li className="divider"></li>
                  <li><a href="#">Delete</a></li>
                </ul>
            </div>
        </div>
    </div>
    );
  }
});

但是,{this.props.showBulkActions吗?'show':'hidden'}。我在这里做错什么吗?


您可能还需要考虑react-bootstrap,因为这会将一些类的东西抽象到组件属性中,从而使您尝试做的事情变得容易一些。
Dancrumb

Answers:


588

大括号位于字符串内,因此被评估为字符串。他们需要在外面,所以应该可以工作:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? 'show' : 'hidden')}>

注意“向右拉”后的空格。您不想意外地提供类“ pull-rightshow”而不是“ pull-right show”。括号也必须存在。


3
谢谢!我必须稍作修改,因为出于某种原因它根本没有输出btn-group pull-right。只是显示或隐藏。
apexdodge

这在某些classnames不合适的情况下特别有用。如果您在render函数中,并且有一个map,则可能只知道在渲染该类时是否要添加一个类,因此此答案对此非常有用。
戴夫·库珀

一个不错的选择,而不是在渲染或返回中包含一堆条件模板
devonj

@apexdodge您必须做的修改。我有同样的问题。
RamY

1
@RamY一种方法是将所有类放入条件内 this.props.showBulkActions ? 'btn-group pull-right show' : 'btn-group pull-right hidden')。不优雅,但可以。
伊恩(Ian)

87

正如其他人所评论的那样,classnames实用程序是当前在ReactJs中处理条件CSS类名称的推荐方法。

在您的情况下,解决方案将如下所示:

var btnGroupClasses = classNames(
  'btn-group',
  'pull-right',
  {
    'show': this.props.showBulkActions,
    'hidden': !this.props.showBulkActions
  }
);

...

<div className={btnGroupClasses}>...</div>

作为附带说明,我建议您尝试避免同时使用showhidden类,因此代码可能更简单。您很可能不需要为默认显示的内容设置类。


11
您能否详细说明classNames实用程序是“当前推荐的方法”?是否在某个地方备受好评的最佳实践文档中记录了这一点?或者只是在React和classNames现在之间的口口相传?
亚历山大·尼德

6
@anied在撰写本文时,在官方的React文档中建议使用它:web.archive.org/web/20160602124910/http
Diego V

3
最新文档中仍然提到:“ 如果您经常发现自己编写这样的代码,则类名包可以简化它。
Franklin Yu

66

如果您使用的是Transpiler(例如Babel或Traceur),则可以使用新的ES6“ 模板字符串 ”。

这是@ spitfire109的答案,并作了相应修改:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>

这种方法可以让您做类似的事情,呈现s-is-showns-is-hidden

<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>

20
在使用第二种方法时要特别小心,尤其是在大型代码库中,因为这会使类字符串不易被抓住。例如,如果有人在s-is-showns-is-hidden在代码库中搜索,他们将找不到该代码。
标记

15

您可以在此处使用字符串文字

const Angle = ({show}) => {

   const angle = `fa ${show ? 'fa-angle-down' : 'fa-angle-right'}`;

   return <i className={angle} />
}

9

花费@ spitfire109的好答案,可以做这样的事情:

rootClassNames() {
  let names = ['my-default-class'];
  if (this.props.disabled) names.push('text-muted', 'other-class');

  return names.join(' ');
}

然后在render函数中:

<div className={this.rootClassNames()}></div>

保持jsx简短





5

2019年

React是Lake的许多实用程序。但是您不需要任何npm包装。只需在某处创建函数classnames并在需要时调用它即可;

function classnames(obj){
  return Object.entries(obj).filter( e => e[1] ).map( e=>e[0] ).join(' ');
}

要么

function classnames(obj){
 return Object.entries(obj).map( ([k,v]) => v?k:'' ).join(' ');
}

  stateClass= {
    foo:true,
    bar:false,
    pony:2
  }
  classnames(stateClass) // return 'foo pony'

 <div className="foo bar {classnames(stateClass)}"> some content </div>

只是为了灵感

声明辅助元素并使用it toggle方法

(DOMToken​List)classList.toggle(class,condition)

例:

const classes = document.createElement('span').classList; 

function classstate(obj){
  for( let n in obj) classes.toggle(n,obj[n]);
 return classes; 
}

4

更优雅的解决方案,更有利于维护和可读性:

const classNames = ['js-btn-connect'];

if (isSelected) { classNames.push('is-selected'); }

<Element className={classNames.join(' ')}/>

3

您可以使用此:

<div className={"btn-group pull-right" + (this.props.showBulkActions ? ' show' : ' hidden')}>

2

这对你有用

var TopicNav = React.createClass({
render: function() {

let _myClasses = `btn-group pull-right {this.props.showBulkActions?'show':'hidden'}`;

return (
            ...
            <div className={_myClasses}>
               ...
            </div>
    );
  }
});

1

您可以使用 npm软件包。它处理所有内容,并具有基于变量或函数的静态和动态类的选项。

// Support for string arguments
getClassNames('class1', 'class2');

// support for Object
getClassNames({class1: true, class2 : false});

// support for all type of data
getClassNames('class1', 'class2', null, undefined, 3, ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames('show', {class1: true, class2 : false})} /> // "show class1"


1

我想补充一点,您也可以将可变内容用作类的一部分

<img src={src} alt="Avatar" className={"img-" + messages[key].sender} />

上下文是机器人与用户之间的聊天,其样式根据发送者而变化,这是浏览器的结果:

<img src="http://imageurl" alt="Avatar" class="img-bot">

1

当您要添加多个类时,这很有用。您可以使用空格将数组中的所有类连接在一起。

const visibility = this.props.showBulkActions ? "show" : ""
<div className={["btn-group pull-right", visibility].join(' ')}>

1

更换:

<div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">`

与:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.