React Js 有条件地应用 class 属性
React Js conditionally applying class attributes
我想根据从父组件传入的内容有条件地显示和隐藏此按钮组,如下所示:
<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'}。我做错了什么吗?
大括号在字符串内部,因此被评估为字符串。他们需要在外面,所以这应该有效:
<div className={"btn-group pull-right " + (this.props.showBulkActions ? 'show' : 'hidden')}>
注意 "pull-right" 之后的 space。您不想意外地提供 class "pull-rightshow" 而不是 "pull-right show"。括号也需要在那里。
正如其他人评论的那样,classnames 实用程序是目前推荐的处理 ReactJs 中条件 CSS class 名称的方法。
对于您的情况,解决方案如下所示:
var btnGroupClasses = classNames(
'btn-group',
'pull-right',
{
'show': this.props.showBulkActions,
'hidden': !this.props.showBulkActions
}
);
...
<div className={btnGroupClasses}>...</div>
作为旁注,我建议您尽量避免同时使用 show
和 hidden
class,这样代码会更简单。很可能,您不需要为默认显示的内容设置 class。
2021 年附录: 为了提高性能,您可以查看 clsx 作为替代方案。
在@spitfire109 的很好的回答上,可以做这样的事情:
rootClassNames() {
let names = ['my-default-class'];
if (this.props.disabled) names.push('text-muted', 'other-class');
return names.join(' ');
}
然后在渲染函数中:
<div className={this.rootClassNames()}></div>
保持 jsx 简短
如果您使用的是转译器(例如Babel or Traceur) you can use the new ES6 "template strings"。
这里是@spitfire109的回答,做相应修改:
<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>
这种方法允许您做类似的事情,渲染 s-is-shown
或 s-is-hidden
:
<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>
或者使用 npm classnames。它非常简单和有用,特别是对于构建 类
的列表
更优雅的方案,更利于维护和可读性:
const classNames = ['js-btn-connect'];
if (isSelected) { classNames.push('is-selected'); }
<Element className={classNames.join(' ')}/>
您可以使用 ES6 数组代替类名。
答案基于 Axel Rauschmayer 博士的文章:Conditionally adding entries inside Array and object literals.
<div className={[
"classAlwaysPresent",
...Array.from(condition && ["classIfTrue"])
].join(" ")} />
您可以使用 this 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"
你可以在这里使用字符串文字
const Angle = ({show}) => {
const angle = `fa ${show ? 'fa-angle-down' : 'fa-angle-right'}`;
return <i className={angle} />
}
这对你有用
var TopicNav = React.createClass({
render: function() {
let _myClasses = `btn-group pull-right {this.props.showBulkActions?'show':'hidden'}`;
return (
...
<div className={_myClasses}>
...
</div>
);
}
});
2019:
React 有很多实用程序。但是你不需要任何 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( ([cls,enb]) => enb? cls: '' ).join(' ');
}
例子
stateClass= {
foo:true,
bar:false,
pony:2
}
classnames(stateClass) // return 'foo pony'
<div className="foo bar {classnames(stateClass)}"> some content </div>
只是为了灵感
声明助手 DOM 元素并使用它的原生 toggle
方法:
(DOMTokenList)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;
}
根据this.props.showBulkActions
的值可以动态切换类如下。
<div ...{...this.props.showBulkActions
? { className: 'btn-group pull-right show' }
: { className: 'btn-group pull-right hidden' }}>
你可以使用这个:
<div className={"btn-group pull-right" + (this.props.showBulkActions ? ' show' : ' hidden')}>
我想补充一点,您还可以使用 变量内容 作为 class
的一部分
<img src={src} alt="Avatar" className={"img-" + messages[key].sender} />
上下文是机器人和用户之间的聊天,样式会根据发件人而变化,这是浏览器结果:
<img src="http://imageurl" alt="Avatar" class="img-bot">
如果您只需要一个可选的 class 姓名:
<div className={"btn-group pull-right " + (this.props.showBulkActions ? "show" : "")}>
当您有多个 class 要追加时,这很有用。您可以使用 space 将所有 classes 加入数组中。
const visibility = this.props.showBulkActions ? "show" : ""
<div className={["btn-group pull-right", visibility].join(' ')}>
参考@split fire的回答,我们可以更新成模板字面量,这样可读性更好,供参考Checkout javascript template literal
<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}>
替换:
<div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">`
与:
<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}
<div className={['foo', condition && 'bar'].filter(Boolean).join(' ')} />
.filter(Boolean)
从数组中删除“虚假”值。由于 class 名称必须是 strings,除此之外的任何内容都不会包含在 new 过滤数组中。
console.log( ['foo', true && 'bar'].filter(Boolean).join(' ') )
console.log( ['foo', false && 'bar'].filter(Boolean).join(' ') )
上面写成一个函数:
const cx = (...list) => list.filter(Boolean).join(' ')
// usage:
<div className={cx('foo', condition && 'bar')} />
var cx = (...list) => list.filter(Boolean).join(' ')
console.log( cx('foo', 1 && 'bar', 1 && 'baz') )
console.log( cx('foo', 0 && 'bar', 1 && 'baz') )
console.log( cx('foo', 0 && 'bar', 0 && 'baz') )
根据参数(如果存在)return 正确 class 的函数
getClass(param){
let podClass = 'classA'
switch(param.toLowerCase()){
case 'B':
podClass = 'classB'
break;
case 'C':
podClass = 'classC'
break;
}
return podClass
}
现在只需从 div 调用此函数,其中将应用相应的 class。
<div className={anyOtherClass + this.getClass(param)}
我成功地使用此逻辑将正确的颜色应用于我的 bootstrap table 行。
例如,您可以简单地执行以下操作。
let classNameDependsOnCondtion = i18n.language == 'en' ? "classname" : "";
className={`flex flex-col lg:flex-row list-none ${classNameDependsOnCondtion }`}
或
className={`flex flex-col lg:flex-row list-none ${i18n.language == 'en' ? "classname" : ""}`}
就用这个办法--
<div className={`${this.props.showActions ? 'shown' : 'hidden'}`}>
这样就干净多了。
<div className={"h-3 w-3 rounded-full my-auto " + (index.endDate ==="present"? "bg-green-500":"bg-red-500")}></div>
Don't Forget to add an extra space after the static class names.
我想根据从父组件传入的内容有条件地显示和隐藏此按钮组,如下所示:
<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'}。我做错了什么吗?
大括号在字符串内部,因此被评估为字符串。他们需要在外面,所以这应该有效:
<div className={"btn-group pull-right " + (this.props.showBulkActions ? 'show' : 'hidden')}>
注意 "pull-right" 之后的 space。您不想意外地提供 class "pull-rightshow" 而不是 "pull-right show"。括号也需要在那里。
正如其他人评论的那样,classnames 实用程序是目前推荐的处理 ReactJs 中条件 CSS class 名称的方法。
对于您的情况,解决方案如下所示:
var btnGroupClasses = classNames(
'btn-group',
'pull-right',
{
'show': this.props.showBulkActions,
'hidden': !this.props.showBulkActions
}
);
...
<div className={btnGroupClasses}>...</div>
作为旁注,我建议您尽量避免同时使用 show
和 hidden
class,这样代码会更简单。很可能,您不需要为默认显示的内容设置 class。
2021 年附录: 为了提高性能,您可以查看 clsx 作为替代方案。
在@spitfire109 的很好的回答上,可以做这样的事情:
rootClassNames() {
let names = ['my-default-class'];
if (this.props.disabled) names.push('text-muted', 'other-class');
return names.join(' ');
}
然后在渲染函数中:
<div className={this.rootClassNames()}></div>
保持 jsx 简短
如果您使用的是转译器(例如Babel or Traceur) you can use the new ES6 "template strings"。
这里是@spitfire109的回答,做相应修改:
<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>
这种方法允许您做类似的事情,渲染 s-is-shown
或 s-is-hidden
:
<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>
或者使用 npm classnames。它非常简单和有用,特别是对于构建 类
的列表更优雅的方案,更利于维护和可读性:
const classNames = ['js-btn-connect'];
if (isSelected) { classNames.push('is-selected'); }
<Element className={classNames.join(' ')}/>
您可以使用 ES6 数组代替类名。 答案基于 Axel Rauschmayer 博士的文章:Conditionally adding entries inside Array and object literals.
<div className={[
"classAlwaysPresent",
...Array.from(condition && ["classIfTrue"])
].join(" ")} />
您可以使用 this 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"
你可以在这里使用字符串文字
const Angle = ({show}) => {
const angle = `fa ${show ? 'fa-angle-down' : 'fa-angle-right'}`;
return <i className={angle} />
}
这对你有用
var TopicNav = React.createClass({
render: function() {
let _myClasses = `btn-group pull-right {this.props.showBulkActions?'show':'hidden'}`;
return (
...
<div className={_myClasses}>
...
</div>
);
}
});
2019:
React 有很多实用程序。但是你不需要任何 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( ([cls,enb]) => enb? cls: '' ).join(' ');
}
例子
stateClass= {
foo:true,
bar:false,
pony:2
}
classnames(stateClass) // return 'foo pony'
<div className="foo bar {classnames(stateClass)}"> some content </div>
只是为了灵感
声明助手 DOM 元素并使用它的原生 toggle
方法:
(DOMTokenList)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;
}
根据this.props.showBulkActions
的值可以动态切换类如下。
<div ...{...this.props.showBulkActions
? { className: 'btn-group pull-right show' }
: { className: 'btn-group pull-right hidden' }}>
你可以使用这个:
<div className={"btn-group pull-right" + (this.props.showBulkActions ? ' show' : ' hidden')}>
我想补充一点,您还可以使用 变量内容 作为 class
的一部分<img src={src} alt="Avatar" className={"img-" + messages[key].sender} />
上下文是机器人和用户之间的聊天,样式会根据发件人而变化,这是浏览器结果:
<img src="http://imageurl" alt="Avatar" class="img-bot">
如果您只需要一个可选的 class 姓名:
<div className={"btn-group pull-right " + (this.props.showBulkActions ? "show" : "")}>
当您有多个 class 要追加时,这很有用。您可以使用 space 将所有 classes 加入数组中。
const visibility = this.props.showBulkActions ? "show" : ""
<div className={["btn-group pull-right", visibility].join(' ')}>
参考@split fire的回答,我们可以更新成模板字面量,这样可读性更好,供参考Checkout javascript template literal
<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}>
替换:
<div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">`
与:
<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}
<div className={['foo', condition && 'bar'].filter(Boolean).join(' ')} />
.filter(Boolean)
从数组中删除“虚假”值。由于 class 名称必须是 strings,除此之外的任何内容都不会包含在 new 过滤数组中。
console.log( ['foo', true && 'bar'].filter(Boolean).join(' ') )
console.log( ['foo', false && 'bar'].filter(Boolean).join(' ') )
上面写成一个函数:
const cx = (...list) => list.filter(Boolean).join(' ')
// usage:
<div className={cx('foo', condition && 'bar')} />
var cx = (...list) => list.filter(Boolean).join(' ')
console.log( cx('foo', 1 && 'bar', 1 && 'baz') )
console.log( cx('foo', 0 && 'bar', 1 && 'baz') )
console.log( cx('foo', 0 && 'bar', 0 && 'baz') )
根据参数(如果存在)return 正确 class 的函数
getClass(param){
let podClass = 'classA'
switch(param.toLowerCase()){
case 'B':
podClass = 'classB'
break;
case 'C':
podClass = 'classC'
break;
}
return podClass
}
现在只需从 div 调用此函数,其中将应用相应的 class。
<div className={anyOtherClass + this.getClass(param)}
我成功地使用此逻辑将正确的颜色应用于我的 bootstrap table 行。
例如,您可以简单地执行以下操作。
let classNameDependsOnCondtion = i18n.language == 'en' ? "classname" : "";
className={`flex flex-col lg:flex-row list-none ${classNameDependsOnCondtion }`}
或
className={`flex flex-col lg:flex-row list-none ${i18n.language == 'en' ? "classname" : ""}`}
就用这个办法--
<div className={`${this.props.showActions ? 'shown' : 'hidden'}`}>
这样就干净多了。
<div className={"h-3 w-3 rounded-full my-auto " + (index.endDate ==="present"? "bg-green-500":"bg-red-500")}></div>
Don't Forget to add an extra space after the static class names.