如何添加多个类到一个ReactJS组件?

我是ReactJS和JSX的新手,我对下面的代码有一个小问题。

我试图在每个li上添加多个类到className属性:

<li key={index} className={activeClass, data.class, "main-class"}></li>

我的React组件是:

var AccountMainMenu = React.createClass({
getInitialState: function() {
return { focused: 0 };
},


clicked: function(index) {
this.setState({ focused: index });
},


render: function() {
var self = this;
var accountMenuData = [
{
name: "My Account",
icon: "icon-account"
},
{
name: "Messages",
icon: "icon-message"
},
{
name: "Settings",
icon: "icon-settings"
}
/*{
name:"Help &amp; Support &nbsp; <span class='font-awesome icon-support'></span>(888) 664.6261",
listClass:"no-mobile last help-support last"
}*/
];


return (
<div className="acc-header-wrapper clearfix">
<ul className="acc-btns-container">
{accountMenuData.map(function(data, index) {
var activeClass = "";


if (self.state.focused == index) {
activeClass = "active";
}


return (
<li
key={index}
className={activeClass}
onClick={self.clicked.bind(self, index)}
>
<a href="#" className={data.icon}>
{data.name}
</a>
</li>
);
})}
</ul>
</div>
);
}
});


ReactDOM.render(<AccountMainMenu />, document.getElementById("app-container"));
758112 次浏览

当决定使用(不使用)类需要相当多的逻辑时,我使用一会。一个# EYZ1:

...
var liClasses = classNames({
'main-class': true,
'activeClass': self.state.focused === index
});


return (<li className={liClasses}>{data.name}</li>);
...

也就是说,如果你不想包含依赖项,下面有更好的答案。

也许一会可以帮助你。

var classNames = require('classnames');
classNames('foo', {'xx-test': true, bar: false}, {'ox-test': false}); // => 'foo xx-test'

你可以像这样创建一个有多个类名的元素:

<li className="class1 class2 class3">foo</li>

当然,您可以使用包含类名的字符串,并操作此字符串来更新元素的类名。

var myClassNammes = 'class1 class2 class3';
...
<li className={myClassNames}>foo</li>

我使用ES6 模板文字。例如:

const error = this.state.valid ? '' : 'error'
const classes = `form-control round-lg ${error}`

然后渲染它:

<input className={classes} />

一行程序版本:

<input className={`form-control round-lg ${this.state.valid ? '' : 'error'}`} />

我使用rc-classnames包。

// ES6
import c from 'rc-classnames';


// CommonJS
var c = require('rc-classnames');


<button className={c('button', {
'button--disabled': isDisabled,
'button--no-radius': !hasRadius
})} />

你可以添加任何格式的类(数组,对象,参数)。数组或参数中的所有真值加上对象中等于true的键将合并在一起。

例如:

ReactClassNames('a', 'b', 'c') // => "a b c"
ReactClassNames({ 'a': true, 'b': false, c: 'true' }) // => "a c"
ReactClassNames(undefined, null, 'a', 0, 'b') // => "a b"

香草JS

不需要外部库-只需使用ES6 模板字符串:

<i className={`${styles['foo-bar-baz']} fa fa-user fa-2x`}/>

Concat

不需要花哨,我使用CSS模块,这很容易

import style from '/css/style.css';


<div className={style.style1+ ' ' + style.style2} />

这将导致:

<div class="src-client-css-pages-style1-selectionItem src-client-css-pages-style2">

换句话说,两种风格都有

条件

同样的想法也可以用在“如果”上

const class1 = doIHaveSomething ? style.style1 : 'backupClass';


<div className={class1 + ' ' + style.style2} />

ES6

在过去的一年左右,我一直在使用模板文字,所以我觉得它值得一提,我发现它非常有表现力,易于阅读:

`${class1} anotherClass ${class1}`

这是你如何在ES6中做到这一点:

className = {`
text-right
${itemId === activeItemId ? 'active' : ''}
${anotherProperty === true ? 'class1' : 'class2'}
`}

您可以列出多个类和条件,也可以包括静态类。没有必要添加额外的库。

祝你好运;)

只需使用JavaScript。

<li className={[activeClass, data.klass, "main-class"].join(' ')} />

如果你想在对象中添加基于类的键和值,你可以使用以下方法:

function classNames(classes) {
return Object.entries(classes)
.filter(([key, value]) => value)
.map(([key, value]) => key)
.join(' ');
}


const classes = {
'maybeClass': true,
'otherClass': true,
'probablyNotClass': false,
};


const myClassNames = classNames(classes);
// Output: "maybeClass otherClass"


<li className={myClassNames} />

或者更简单:

const isEnabled = true;
const isChecked = false;


<li className={[isEnabled && 'enabled', isChecked && 'checked']
.filter(e => !!e)
.join(' ')
} />
// Output:
// <li className={'enabled'} />

使用# EYZ0

render() {
return (
<input className={
classnames({
edit: this.props.editing,
'new-todo': this.props.newTodo
})}
type="text"
placeholder={this.props.placeholder}
autoFocus="true"
value={this.state.text}
onBlur={this.handleBlur}
onChange={this.handleChange}
onKeyDown={this.handleSubmit} />
)
}

用普通的js代码替换一会将会是这样的:

render() {
return (
<input
className={`
${this.props.editing ? 'edit' : ''} ${this.props.newTodo ? 'new-todo' : ''}
`}
type="text"
placeholder={this.props.placeholder}
autoFocus="true"
value={this.state.text}
onBlur={this.handleBlur}
onChange={this.handleChange}
onKeyDown={this.handleSubmit} />
)
}

姗姗来迟,但为什么要用第三方来解决这么简单的问题呢?

你可以像@Huw Davies提到的那样——最好的方法

1. <i className={`${styles['foo-bar-baz']} fa fa-user fa-2x`}/>
2. <i className={[styles['foo-bar-baz'], 'fa fa-user', 'fa-2x'].join(' ')}

两者都很好。但对于大型应用程序来说,编写可能会变得复杂。为了使其达到最佳效果,我做了上面相同的事情,但将其放在一个helper类中

使用下面的helper函数,可以让我保持逻辑独立,以便将来编辑,还提供了多种方式来添加类

classNames(styles['foo-bar-baz], 'fa fa-user', 'fa-2x')

classNames([styles['foo-bar-baz], 'fa fa-user', 'fa-2x'])

下面是我的辅助函数。我把它放在help .js中,我把所有常用方法都放在那里。这样一个简单的功能,我避免使用第三方来保持控制

export function classNames (classes) {
if(classes && classes.constructor === Array) {
return classes.join(' ')
} else if(arguments[0] !== undefined) {
return [...arguments].join(' ')
}
return ''
}

只要添加,我们就可以过滤掉空字符串。

className={[
'read-more-box',
this.props.className,
this.state.isExpanded ? 'open' : 'close',
].filter(x => !!x).join(' ')}

我就是这么做的:

组件:

const Button = ({ className }) => (
<div className={ className }> </div>
);

调用组件:

<Button className = 'hashButton free anotherClass' />

这可以通过ES6模板文字实现:

<input className={`base-input-class ${class1} ${class2}`}>

(为清晰起见,经过编辑)

如果您不想导入另一个模块,这个函数可以像classNames模块一样工作。

function classNames(rules) {
var classes = ''


Object.keys(rules).forEach(item => {
if (rules[item])
classes += (classes.length ? ' ' : '') + item
})


return classes
}

你可以这样使用它:

render() {
var classes = classNames({
'storeInfoDiv': true,
'hover': this.state.isHovered == this.props.store.store_id
})


return (
<SomeComponent style={classes} />
)
}

bind classNames导入css模块到组件中。

import classNames from 'classnames';
import * as styles from './[STYLES PATH];
const cx = classNames.bind(styles);

classnames提供了以声明的方式为React元素声明className的能力。

例:

<div classNames={cx(styles.titleText)}> Lorem </div>


<div classNames={cx('float-left')}> Lorem </div> // global css declared without css modules
<div classNames={cx( (test === 0) ?
styles.titleText :
styles.subTitleText)}>  Lorem </div> // conditionally assign classes


<div classNames={cx(styles.titleText, 'float-left')}> Lorem </div> //combine multiple classes

我使用React 16.6.3和@Material UI 3.5.1,并且能够在className中使用数组,如className={[classes.tableCell, classes.capitalize]}

所以在你的例子中,下面是类似的。

<li key={index} className={[activeClass, data.class, "main-class"]}></li>

使用# EYZ0

import classNames from classNames;

  1. 可以使用多个类使用逗号分隔:

    <li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li>
    
  2. Can use multiple classes using comas separated with condition:

    <li className={classNames(classes.buttonArea, !nodes.length && classes.buttonAreaHidden)}>Hello World</li>
    

Using array as props to classNames will also work, but gives warning e.g.

className={[classes.tableCellLabel, classes.tableCell]}

你可以像这样创建一个具有多个类名的元素,我尝试了这两种方式,工作正常…

如果你导入任何css,那么你可以这样做: 方法1:

import React, { Component, PropTypes } from 'react';
import csjs from 'csjs';
import styles from './styles';
import insertCss from 'insert-css';
import classNames from 'classnames';
insertCss(csjs.getCss(styles));
export default class Foo extends Component {
render() {
return (
<div className={[styles.class1, styles.class2].join(' ')}>
{ 'text' }
</div>
);
}
}

# EYZ0

import React, { Component, PropTypes } from 'react';
import csjs from 'csjs';
import styles from './styles';
import insertCss from 'insert-css';
import classNames from 'classnames';
insertCss(csjs.getCss(styles));
export default class Foo extends Component {
render() {
return (
<div className={styles.class1 + ' ' + styles.class2}>
{ 'text' }
</div>
);
}
}

**

如果你应用css作为内部:

const myStyle = {
color: "#fff"
};


// React Element using Jsx
const myReactElement = (
<h1 style={myStyle} className="myClassName myClassName1">
Hello World!
</h1>
);


ReactDOM.render(myReactElement, document.getElementById("app"));
.myClassName {
background-color: #333;
padding: 10px;
}
.myClassName1{
border: 2px solid #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<div id="app">
  

</div>

我认为我们不需要使用一个外部包来添加多个类。

我个人使用

<li className={`li active`}>Stacy</li>

<li className={`li ${this.state.isActive ? 'active' : ''}`}>Stacy<li>

<li className={'li ' + (this.state.isActive ? 'active' : '') }>Stacy<li>

第二个和第三个,以防您需要有条件地添加或删除类。

要添加更多的类

... className={`${classes.hello} ${classes.hello1}`...

您可以使用数组,然后使用空间将它们连接起来。

<li key={index} className={[activeClass, data.class, "main-class"].join(' ')}></li>

这将导致:

<li key={index} class="activeClass data.class main-class"></li>

你可以这样做:

<li key={index} className={`${activeClass} ${data.class} main-class`}></li>

一个简单的解决方法,希望能有所帮助。

它可以用https://www.npmjs.com/package/clsx完成:

https://www.npmjs.com/package/clsx

首先安装它:

npm install --save clsx

然后将它导入到组件文件中:

import clsx from  'clsx';

然后在组件中使用导入的函数:

<div className={ clsx(classes.class1, classes.class2)}>

我知道这是一个晚的回答,但我希望这能帮助到一些人。

假设你已经在css文件“主要的”,“font-i”,“font-xl”中定义了以下类

  • 第一步是导入CSS文件。
  • 然后

<h3 class = {` ${'primary'} ${'font-i'} font-xl`}> HELLO WORLD </h3>

would do the trick!

For more info: https://www.youtube.com/watch?v=j5P9FHiBVNo&list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&index=20

我通常这样使用它:(在你的情况下)

    <li  key={index} className={
"component " +
`${activeClass? activeClass: " not-an-active-class "}` +
`${data.class? " " + data.class : " no-data-class "}`
} />

当涉及到JSX和(通常)我们有一些json…然后你循环它…# EYZ0。地图,加上一些条件来检查json属性是否存在,以根据json中的属性值呈现类名。在下面的例子中,component_colorcomponent_dark_shade是来自component.map()的属性

   <div className={
"component " +
`${component_color? component_color: " no-color "}` +
`${component_dark_shade? " " + component_dark_shade : " light "}`
}/>

输出:<div class="component no-color light" .... 或者:<div class="component blue dark" ....,这取决于map的值…< / p >

当我有很多不同的课程时,我发现以下内容很有用。

过滤器删除任何null值,连接将所有剩余值放入空格分隔的字符串中。

const buttonClasses = [
"Button",
disabled ? "disabled" : null,
active ? "active" : null
].filter((class) => class).join(" ")


<button className={buttonClasses} onClick={onClick} disabled={disabled ? disabled : false}>

如果你想使用双条件css模块总是莫名其妙,所以我建议你遵循这个模式

import styles from "./styles.module.css"


const Conditonal=({large, redColor}) => {
return(
<div className={[large && styles.large] + [redColor && styles.color]>
...
</div>
)
}


export default Conditonal

如果它只是一个有两个类名的条件语句,使用这个

import styles from "./styles.module.css"


const Conditonal=({redColor}) => {
return(
<div className={styles.large + [redColor && styles.color]>
...
</div>
)
}


export default Conditonal

创建一个这样的函数

function cssClass(...c) {
return c.join(" ")
}

需要时打电话给它。

<div className={cssClass("head",Style.element,"black")}><div>

只要用逗号!

const useStyles = makeStyles((theme) => ({
rightAlign: {
display: 'flex',
justifyContent: 'flex-end',
},
customSpacing: {
marginTop: theme.spacing(2.5),
},
)};


<div className={(classes.rightAlign, classes.customSpacing)}>Some code</div>

clsx使这个简单!

clsx函数可以接受任意数量的参数,每个参数都可以 可以是对象、数组、布尔值或字符串。

——npmjs.com上的CLSX文档

进口:

import clsx from 'clsx'

使用它:

<li key={index} className={clsx(activeClass, data.class, "main-class")}></li>

一般来说,人们喜欢

<div className={  `head ${style.class1} ${Style.class2}`  }><div>

<div className={  'head ' + style.class1 + ' ' + Style.class2 }><div>

<div className={  ['head', style.class1 , Style.class2].join(' ')  }><div>

但是您可以选择创建一个函数来完成这项工作

function joinAll(...classes) {
return classes.join(" ")
}

然后叫它:-

<div className={joinAll('head', style.class1 , style.class2)}><div>

这似乎对我有用

<Link className={[classes.button, classes.buttonFirst]}>

使用jbcn模块。(本支持)

https://www.npmjs.com/package/jbcn

例子:

const classNames = jbcn({
btn: {
alpha: true,
beta: true,
gamma: false
}
});


// ==> "btn btn--alpha btn--beta"
const classNames = jbcn({
expand: true,
hide: false,


btn: {
alpha: true,
beta: true,
gamma: false
}
});


// ==> "expand btn btn--alpha btn--beta"

我使用了这个语法

    <div
className={[
"d-inline-flex justify-content-center align-items-center ",
withWrapper && `ft-icon-wrapper ft-icon-wrapper-${size}`,
wrapperClass,
].join(" ")}
>
<img
className={`ft-icon ft-icon-${size} ${iconClass}`}
alt={id}
src={icon}
/>
</div>

使用CSS模块(或Sass模块),你也可以把你的样式隔离到一个特定的组件。

“组件范围的CSS允许你编写传统的、可移植的CSS,并且副作用最小:不用担心选择器名称冲突或影响其他组件的样式。”

import * as styles from "./whatever.module.css"  // css version
import * as styles from "./whatever.module.scss" // sass version


<div className={`${styles.class1} ${styles.class2}`}>
INSERT YOUR CODE HERE
</div>

Ref1 # EYZ0 < / p >

使用字符串连接来连接CSS类是个坏主意。在很多情况下,这是非常令人困惑和压倒性的。最好添加一些简单的帮助器,将所有这些连接到一个字符串中。这里有一个例子:

import isString from 'lodash/isString';
import isObject from 'lodash/isObject';
/**
* Helper function for conditionally creating css class strings.
*
* Example usage:
*   classNames('foo', ['bar', ''], { baz: false, bob: true });
*   => 'foo bar bob'
*
* @module helpers/classNames
* @param {...(String|String[]|Object)} args
* @returns {String}
*/
export default function classNames(...args) {
const classes = [];
for (const arg of args) {
if (arg !== null && typeof arg !== 'undefined') {
if (isString(arg)) {
classes.push(arg);
} else if (Array.isArray(arg)) {
classes.push(classNames(...arg));
} else if (isObject(arg)) {
classes.push(classNames(...Object.keys(arg).filter(k => arg[k])));
}
}
}
return classes.join(' ');
}

(从# EYZ0)