ChatGPT解决这个技术问题 Extra ChatGPT

如何向 ReactJS 组件添加多个类?

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

我正在尝试向每个 liclassName 属性添加多个类:

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

我的反应组件是:

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"));
我在这里找到了一个简短的答案stackoverflow.com/a/36209517/4125588,只需使用 JavaScript 加入这个类,静态或动态,使用“+”运算符,记得在除第一个之外的类之前插入“”,因为 HTML 中的真实类应该是这样的'ab c',也是它们之间的空格。
为什么 classNames={{foo: true, bar: true, baz: false}}classNames={["foo", "bar"]} 不能工作
那你为什么只为 li 元素分配一个类名“active”?
您可以查看 npmjs.com/package/@ivanhanak_com/react-join-classnames,基本上您可以在其中使用 <div className={classes(isTrue && "willRenderThisClass")} />

D
Damian Pavlica

我使用 ES6 template literals。例如:

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'}`} />

这导致 <input class=" form-control input-lg round-lg" />。请注意开头的额外空间。这是有效的,但丑陋。甚至 react FAQ 推荐另一种方式或使用类名包:reactjs.org/docs/faq-styling.html
我无法理解您为什么要导入一个库(如已接受的答案)来设置一些可以使用 Vanilla JavaScript 设置的类,无论如何,这是一种更高效、更清洁、更易读的解决方案。
这是正确的答案。如“正确”答案中所建议的那样使用依赖项是过分的。
我总是喜欢这个答案,但不喜欢最后的额外空间,以防错误值。您可以使用 trim() 轻松避免。
@CodyMoniz 这个答案引导我朝着正确的方向前进!我有一种情况,我需要添加多个“变量”类。 className={ `${ props.variable } ${ props.variabletwo }` } 成功了!几个小时不知道如何搜索这个,通过这个答案补救。
J
Jack

当决定(不)使用的类需要大量逻辑时,我使用 classnames。一个过于简单的例子

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

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

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


太糟糕了,您必须引入一个类名库才能将两个类添加到一个元素:(
@user959690 这是一个例子。当你经常做这些事情并且你对何时需要应用类有复杂的逻辑时,这个库非常好。如果您正在做一些简单的事情,那么请确保只使用模板,但每种情况都不同,读者应该为他们的工作选择正确的工具。
@user959690 值得注意的是它现在是 installed by NPM when using Webpack,所以 import classNames from 'classnames' 然后在组件 className={classNames(classes.myFirstClass, classes.mySecondClass)} 中使用。
无需使用外部库,请参阅下面的答案。
图书馆还有其他优点:var btnClass = classNames({ btn: true, 'btn-pressed': this.state.isPressed, 'btn-over': !this.state.isPressed && this.state.isHovered }); return <button className={btnClass}>{this.props.label}</button>;
0
0xcaff

只需使用 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'} />

这是对我有用的行:className={['terra-Table', medOrder.resource.status]}
@DougWilhelm 我认为这行不通。它隐式调用 toString 并创建一个逗号分隔的类列表。 github.com/facebook/react/issues/3138
使用 className={[listOfClasses].join(' ')} 的好主意它对我有用,谢谢!
我更喜欢更性感的 className={[activeClass, data.klass, "main-class"].filter(Boolean).join(' ')}
@0xcaff 完美运行
J
Jamie Hutber

康卡特

无需花哨,我正在使用 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">

换句话说,两种风格

条件句

与 if 一起使用相同的想法会很容易

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

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

ES6

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

`${class1} anotherClass ${class1}`

这对我有用,以及“-”名称,即:
大声笑,我头脑发热,答案很简单:D。顺便说一句,这也适用于 CSS 加载器模块
这样做的问题是你不能有可选的类(如果未定义,那么它不会被添加),所以它取决于你确定你的类不为空(不是可选的)。在可选的情况下,没有比 classes() 这样的助手更好的了。我们可以将三元组与 className={slider${className? `${className}: ''}}`。但是很多。 [注:'某事'+未定义='某事欠佳'。 js动态转换。
当然可以,只需在上面声明一个变量并有条件地使用它:)
忘记一切实际上只是JavaScript,从未尝试过。谢谢,帮了大忙。
C
Cody Moniz

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

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

(为清楚起见进行了编辑)


这几乎对我有用,我只需要插入 class1 并且没有更多错误,所以它看起来像这样 <input className={`${class1} ${class2}`}>
因此,如果 class1 不存在,您最终会在中间出现那个大空白。
是的,这将以空格结尾。如果您不想要空格,可以使用:<input className={['base-input-class', class1, class2].filter(x => x).join(' ')} />
n
nightlyop

您可以创建一个具有多个类名的元素,如下所示:

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

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

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

你测试过这个吗?我做到了:)
是的,我做到了。实际上,我经常使用它,但只是看到并纠正了一个错字。当然,第一行中包含类名的字符串必须使用 " 而不是 '。对于那个很抱歉。
H
Hristo Eftimov

使用 ES6 可以做到这一点:

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

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

祝你好运 ;)


考虑到所有额外的空白,这会导致 HTML 非常难看。
没必要这么写。这只是一个更好地解释解决方案的示例。并且总是在生产中你有缩小版本:)
字符串文字在生产中不会被缩小。
H
Huw Davies

香草JS

不需要外部库 - 只需使用 ES6 template strings

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

Vanilla JS 不是 ES6。但我确实喜欢你的例子。
@RyanNerd 你的意思是“ES6 不是香草 JS”吗?无论如何,它是,因为 vanilla js 意味着没有任何框架的 javascript。 ES6 是 javascript 的更新版本。 - stackoverflow.com/a/20435685/5111113
不是一个错误的答案,但可以改进很多。例如,其他所有人都添加了有关状态的示例。
这看起来很干净,肯定更适合这个简单的案例。但值得一提的是,当有多个依赖于状态的类时,模板字符串可能会变得非常难以编写和阅读。在这些情况下,使用 classnames 库会使生活更轻松。但同样,对于这样一个简单的例子,模板字符串肯定是要走的路!
P
Pasham Akhil Kumar Reddy

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

我个人使用

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

或者

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

或者

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

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


这将只添加一个类。
@TrickOrTreat 不正确。上面的所有示例都将添加两个类(如果 isActive 为真)。
为什么除了这个之外还有其他答案?
a
ashuvssut

一般人都喜欢

<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>

x
xsong

也许 classnames 可以帮助您。

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

你能让这个例子更有用吗?
我相信 clsx(npmjs.com/package/clsx) 是类名的一个很好的替代品。
A
Alberto Perez

您可以执行以下操作:

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

一个简短而简单的解决方案,希望这会有所帮助。


海事组织这是最好的答案! :)
Y
Yanga

可以使用 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)}>

H
Himanshu Jariyal

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

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

a
arvinda kumar

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

如果您导入任何 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>
    );
  }
}

方式2:

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 应用为 internal :

常量 myStyle = { 颜色:“#fff”}; // React Element 使用 Jsx const myReactElement = (

Hello World!

); ReactDOM.render(myReactElement, document.getElementById("app")); .myClassName { 背景颜色:#333;填充:10px; } .myClassName1{ 边框:2px 实心 #000; }


.join(' ') 很好。但我们可以避免这种情况并使用模板字符串 className={${styles.class1} ${styles.class2}}
R
ROOT

更多课程添加

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

A
Achintha Isuru

我知道这是一个迟到的答案,但我希望这会对某人有所帮助。

考虑到您在 css 文件 'primary'、'font-i'、'font-xl' 中定义了以下类

第一步是导入 CSS 文件。

然后

HELLO WORLD

会成功的!

欲了解更多信息:https://www.youtube.com/watch?v=j5P9FHiBVNo&list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&index=20


a
atazmin

这似乎对我有用

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

在 TypeScript 中,这给了我:Type 'string[]' is not assignable to type 'string'.
j
jasonleonhard

使用 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 Ref2


s
scazzy

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

你可以像@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(' ')}

两者都很好。但是对于大型应用程序而言,编写可能会变得复杂。为了使其最佳化,我做了同样的事情,但把它放在一个帮助类中

使用我下面的辅助函数,允许我将逻辑分开以供将来编辑,并且还为我提供了多种添加类的方法

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

或者

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

这是我下面的辅助函数。我把它放在了一个 helper.js 中,我保留了我所有的常用方法。作为一个如此简单的功能,我避免使用 3rd 方来保持控制

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

V
Vinay Jariya

您可以使用数组,然后使用空格连接它们。

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

这将导致:

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

h
himansa eshan

创建一个这样的函数

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

需要时调用它。

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

M
Michael Murphy

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

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

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

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

V
Vlad Bezden

使用 facebook's TodoTextInput.js example

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

S
Seth

如果您不想导入另一个模块,此函数的工作方式类似于 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} />
    )
}

如果你可以对 map 或 reduce 做同样的事情,为什么还要使用闭包呢? function classNames(rules) { return Object.entries(rules) .reduce( (arr, [cls, flag]) => { if (flag) arr.push(cls); return arr }, [] ).join(" ") }
J
Jitesh Prajapati

使用https://www.npmjs.com/package/classnames

从“类名”导入类名;

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

  • Total
  • 可以使用多个使用逗号分隔的类:
  • Hello World
  • 使用数组作为类名的道具也可以,但会发出警告,例如

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

    C
    Caleb Hensley

    clsx 让这一切变得简单!

    “clsx 函数可以接受任意数量的参数,每个参数都可以是对象、数组、布尔值或字符串。” -- npmjs.com 上的 clsx 文档

    导入它:

    import clsx from 'clsx'
    

    用它:

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

    S
    Saurav gupta

    我使用了这个语法

        <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>
    

    已经建议了两种解决方案(连接和模板文字)。请解释你的不同之处
    R
    RegarBoy

    我就是做这个的:

    零件:

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

    调用组件:

    <Button className = 'hashButton free anotherClass' />
    

    D
    Devakhim

    我正在使用 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>
    

    这就是我正在做的(尽管没有 MUI)并且不起作用,只适用于第一类 - 没有警告或抱怨。