React Js有条件地应用类属性

ape*_*dge 287 javascript css class-attributes reactjs twitter-bootstrap-3

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

<TopicNav showBulkActions={this.__hasMultipleSelected} />
Run Code Online (Sandbox Code Playgroud)

....

__hasMultipleSelected: function() {
  return false; //return true or false depending on data
}
Run Code Online (Sandbox Code Playgroud)

....

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>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

然而,{this.props.showBulkActions?没有发生任何事情?'show':'hidden'}.我在这里做错了吗?

spi*_*109 511

花括号在字符串内部,因此它被评估为字符串.他们需要在外面,所以这应该工作:

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

注意"右拉"后的空格.您不希望意外地提供"pull-rightshow"类而不是"pull-right show".括号也需要在那里.

  • 谢谢!我不得不稍作修改,因为某种原因它根本没有输出btn-group pull-right。只是显示或隐藏。 (2认同)

Die*_*o V 79

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

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

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

...

<div className={btnGroupClasses}>...</div>
Run Code Online (Sandbox Code Playgroud)

作为一个方面说明,我建议你尽量避免同时使用showhidden类,因此代码可以更简单.很可能您不需要为默认情况下显示的内容设置类.

  • 你能详细说明classNames实用程序是"目前推荐的方法"吗?这是在一些备受推崇的最佳实践文档中捕获的吗?或者只是在React和"classNames"周围的口碑? (9认同)
  • 在撰写本文时,它在官方React文档中被推荐:http://web.archive.org/web/20160602124910/http://facebook.github.io:80/react/docs/class-name-manipulation html的 (5认同)
  • [最新文档]中仍然提到它(https://web.archive.org/web/20180829094008/https://reactjs.org/docs/faq-styling.html#how-do-i-add-css- classes-to-components):"*如果你经常发现自己编写这样的代码,那么classnames包可以简化它.*" (3认同)
  • 截至 2021 年,您可能想尝试使用 [clsx](https://www.npmjs.com/package/clsx),而不是“类名” (2认同)

Ber*_*and 57

如果您使用的是转换器(例如Babel或Traceur),则可以使用新的ES6" 模板字符串 ".

以下是@ spitfire109的答案,相应修改:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>
Run Code Online (Sandbox Code Playgroud)

这种方法允许你做这样的整洁的事情,渲染s-is-showns-is-hidden:

<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>
Run Code Online (Sandbox Code Playgroud)

  • 小心第二种方法,特别是在大型代码库中,因为它使类字符串不那么容易上瘾.例如,如果有人在代码库中搜索"s-is-shown"或"s-is-hidden",他们将找不到此代码. (13认同)

Has*_*ran 27

例如,您可以简单地执行以下操作。

let classNameDependsOnCondtion = i18n.language == 'en' ? "classname" : "";

className={`flex flex-col lg:flex-row list-none ${classNameDependsOnCondtion }`}
Run Code Online (Sandbox Code Playgroud)

或者

className={`flex flex-col lg:flex-row list-none ${i18n.language == 'en' ? "classname" : ""}`}
Run Code Online (Sandbox Code Playgroud)

  • 如果您有条件地内联渲染单个 className 并且不希望在其中一个条件下出现类,则可以返回“null”或“undefined”而不是空字符串。示例:`className={条件?'red' : null}` 或 `className={condition ? 'red' : undefined}` 最好保持标记干净,而不是让元素看起来像 `&lt;div class&gt;` 或 `&lt;div class="null"&gt; (3认同)

Mus*_*usa 14

你可以在这里使用字符串文字

const Angle = ({show}) => {

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

   return <i className={angle} />
}
Run Code Online (Sandbox Code Playgroud)


vsy*_*ync 11

<div className={['foo', condition && 'bar'].filter(Boolean).join(' ')} />
Run Code Online (Sandbox Code Playgroud)

.filter(Boolean)从数组中删除“错误”值。由于类名必须是strings,因此除此之外的任何内容都不会包含在新的过滤数组中。

<div className={['foo', condition && 'bar'].filter(Boolean).join(' ')} />
Run Code Online (Sandbox Code Playgroud)

上面写成一个函数

const cx = (...list) => list.filter(Boolean).join(' ')

// usage:
<div className={cx('foo', condition && 'bar')} />
Run Code Online (Sandbox Code Playgroud)

console.log(  ['foo', true  && 'bar'].filter(Boolean).join(' ')  )
console.log(  ['foo', false && 'bar'].filter(Boolean).join(' ')  )
Run Code Online (Sandbox Code Playgroud)


fla*_*aky 9

在@ spitfire109的完美答案上,可以做到这样的事情:

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

  return names.join(' ');
}
Run Code Online (Sandbox Code Playgroud)

然后在渲染函数中:

<div className={this.rootClassNames()}></div>
Run Code Online (Sandbox Code Playgroud)

保持jsx短


Sur*_*raj 9

只需使用这种方法——

<div className={`${this.props.showActions ? 'shown' : 'hidden'}`}>
Run Code Online (Sandbox Code Playgroud)

这更加整洁和干净。


Pen*_*eck 7

或者使用npm 类名.它非常简单有用,尤其适用于构造类列表


chi*_*s0v 7

如果您只需要一个可选的类名:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? "show" : "")}>
Run Code Online (Sandbox Code Playgroud)

  • 当条件失败时,这将附加“false”类。 (2认同)

Ami*_*wal 7

代替:

<div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">`
Run Code Online (Sandbox Code Playgroud)

和:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}
Run Code Online (Sandbox Code Playgroud)


Nat*_*Ben 6

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

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

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

<Element className={classNames.join(' ')}/>
Run Code Online (Sandbox Code Playgroud)


Tud*_*rar 6

您可以使用ES6数组代替类名。答案基于Axel Rauschmayer博士的文章:有条件地在Array和对象文字中添加条目

<div className={[
                 "classAlwaysPresent", 
                 ...Array.from(condition && ["classIfTrue"])
                ].join(" ")} />
Run Code Online (Sandbox Code Playgroud)


per*_*mon 5

2019年

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

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

要么

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

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

Run Code Online (Sandbox Code Playgroud)

 <div className="foo bar {classnames(stateClass)}"> some content </div>
Run Code Online (Sandbox Code Playgroud)

启发奖金

您可以声明helper元素并使用他的

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

像这样写

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

function classstate(obj){
 return Object.entries(obj).forEach( ([k,v]) => classes.toggle(k,v) ).value;
}

//Or

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

Run Code Online (Sandbox Code Playgroud)