ReactJSコンポーネントに複数のクラスを追加する方法


346

私はReactJSとJSXを初めて使用し、以下のコードに少し問題があります。

classNameそれぞれの属性に複数のクラスを追加しようとしていますli

<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"));

私はここで簡潔な答えを見つけましたstackoverflow.com/a/36209517/4125588、JavaScriptを使用して静的または動的にこのクラスに参加し、「+」演算子を使用して、最初のクラス以外のクラスの前に「 HTMLのクラスは 'ab c'のようにする必要があります。
Fadeoc Khaos 2017


1
なぜしないclassNames={{foo: true, bar: true, baz: false}}classNames={["foo", "bar"]}だけ仕事
Peter V.Mørch

回答:


221

私が使用してクラス名を(しない)の使用にクラスを決定するために必要なロジックのかなりの量があるとき。過度に単純な例

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

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

とはいえ、依存関係を含めたくない場合は、以下のより適切な答えがあります。


188
要素に2つのクラスを追加するためだけにクラス名のライブラリを
取り込む必要があるのは残念です

4
@ user959690これは例です。このライブラリは、これらのことを頻繁に行っており、クラスを適用する必要があるかどうかに複雑なロジックがある場合に非常に便利です。単純なことを行う場合は、必ずテンプレートを使用してください。ただし、すべてのケースが異なり、読者は自分の仕事に適したツールを選択する必要があります。
ジャック

7
@ user959690 Webpack を使用するときにNPMによってインストールされるためimport classNames from 'classnames'、コンポーネントで使用することに注意してくださいclassName={classNames(classes.myFirstClass, classes.mySecondClass)}
Hooligancat

5
外部ライブラリを使用する必要はありません。以下の私の回答を参照してください。
Huw Davies

1
ライブラリは、他の利点があります: 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>;
AmitJS94

395

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

157
また、<input className={`class1 ${class2}`}>
コーディモニスは

3
@unyo私がコメントできるように、コメントとして回答を投稿してください。それはそれだけに値する。私はこれと同じくらい簡単なものを1時間探していましたが、今ではこれがコメントとして埋め込まれています。ありがとうございました。
Souvik Ghosh 2017

これはをもたらし<input class=" form-control input-lg round-lg" />ます。最初の余分なスペースに注意してください。これは有効ですが、醜いです。反応FAQでも別の方法またはclassnamesパッケージの使用を推奨しています:reactjs.org/docs/faq-styling.html
Nakedible

どうしてもライブラリをインポートして(受け入れられた回答のように)、Vanilla JavaScriptを使用して設定できるいくつかのクラスを設定するだけの理由を理解できません。
マーカスパーソンズ

2
これが正解です。「正しい」答えで提案されているように、これに依存関係を使用するのはやり過ぎです。
TheDarkIn1978

171

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]}
ダグウィルヘルム

1
@DougWilhelmうまくいくとは思いません。暗黙的にtoStringを呼び出し、クラスのコンマ区切りリストを作成します。github.com/facebook/react/issues/3138
0xcaff

6
className={[listOfClasses].join(' ')}それを使用するのは良い考えです。
Ala Eddine JEBALI 2018年

98

連結

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

1
これは、 '-'の名前と一緒に機能しました。つまり、<nav className = {styles.navbar + "" + styles ['navbar-default']}>
Flinkman

笑、私は私の頭を割って、答えは単純な連結です:D。ところで、これもCSSローダーモジュールで動作します
GusDeCooL 2017年

それに関する問題は、オプションのクラスを持つことができない(未定義の場合、追加されない)ことです。そのため、クラスがnullではない(オプションではない)かどうかが確実に異なります。オプションの場合は、classes()のようなヘルパーよりも優れています。そのclassName={スライダーのようなテンプレートで三項を使用できます$ {className?`$ {className} : ''}}` `。しかし、それはたくさんあります。[注: 'something' + undefined = 'something underfined'。Js動的変換。
Mohamed Allal 2018年

もちろん、上記の変数を宣言して条件付きで使用するだけです:)
Jamie Hutber

42

これはES6テンプレートリテラルで実現できます。

<input className={`class1 ${class2}`}>

1
これはほとんど問題なく機能し、class1も補間するだけでエラーは発生しなかったので、次のようになります <input className={`${class1} ${class2}`}>
Kingston Fortune

35

次のように、複数のクラス名を持つ要素を作成できます。

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

当然、クラス名を含む文字列を使用し、この文字列を操作して要素のクラス名を更新できます。

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

1
これをテストしましたか?私はしました:)
レイヴン

はい、そうしました。実際、私はそれを頻繁に使用していますが、タイプミスを見て修正しました。もちろん、最初の行にクラス名を含む文字列は、の"代わりに使用する必要があり'ます。申し訳ありません。
nightlyop 2016年

20

これは、ES6でこれを行う方法です。

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

複数のクラスと条件を一覧表示でき、静的クラスを含めることもできます。追加のライブラリを追加する必要はありません。

幸運を ;)


2
これにより、余分な空白をすべて考慮に入れると、非常に見苦しいHTMLになります。
Nakedible

2
そのように書く必要はありません。これは、ソリューションをよりよく説明するための単なる例です。そして常に本番
環境で

18

バニラJS

外部ライブラリは必要ありません-ES6 テンプレート文字列を使用してください

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

バニラJSはES6ではありません。しかし、私はあなたの例が好きです。
RyanNerd

8
@RyanNerd「ES6はバニラJSではない」という意味ですか?とにかく、そうです、バニラjsはフレームワークのないjavascriptを意味します。ES6は、JavaScriptの新しいバージョンです。- stackoverflow.com/a/20435685/5111113
ヒュー・デイヴィス

間違った答えではありませんが、大幅に改善される可能性があります。たとえば、他の誰もが州に関する例を追加しました。
JGallardo

10

たぶんクラス名が役立つでしょう。

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

1
この例をもっと使いやすくしてくれませんか。
JGallardo

9

複数のクラスを追加するためだけに外部パッケージを使用する必要はないと思います。

個人的に使用

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

または

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

2つ目は、条件付きでクラスを追加または削除する必要がある場合に備えています。


1
これにより、いずれかの方法で1つのクラスのみが追加されます。
TrickOrTreat

6

追加するだけで、空の文字列を除外できます。

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

6

このように複数のクラス名で要素を作成できます。私はこれらを両方の方法で試しましたが、うまくいきます...

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を内部として適用する場合:

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>


6

次のことができます。

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

短くてシンプルな解決策、これが役立つことを願っています。



4

パーティーには遅れますが、なぜこのような単純な問題にサードパーティを使用するのでしょうか。

@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に入れました。とてもシンプルな機能なので、サードパーティを使用して制御を維持することを避けました

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

3

配列を使用してから、スペースを使用してそれらを結合できます。

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

これは次の結果になります:

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

3

私はこれが遅い答えであることを知っていますが、これが誰かを助けることを願っています。

次のクラスをcssファイルで定義したことを考慮してください ' primary '、 ' font-i '、 ' font-xl '

  • 最初のステップは、CSSファイルをインポートすることです。
  • その後

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

トリックを行います!

詳細:https : //www.youtube.com/watch?v=j5P9FHiBVNo&list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&index=20



2

FacebookのTodoTextInput.jsの例を使用する

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

2

別のモジュールをインポートしたくない場合は、この関数は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(" ") }
ЕвгенийСавичев

1

それが私がすることです:

成分:

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

呼び出しコンポーネント:

<Button className = 'hashButton free anotherClass' />

1

私は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はありません)、機能せず、最初のクラスのみを適用します-警告や不満はありません。
Juan Lanus

1

https://www.npmjs.com/package/classnamesを使用してください

'classnames'からclassNamesをインポートします。

  1. カンマ区切りで複数のクラスを使用できます:

    <li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li>
  2. 条件で区切られたコマを使用して複数のクラスを使用できます:

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

classNamesのプロパティとして配列を使用することもできますが、警告が表示されます。

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


0

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

クラスは任意の形式(配列、オブジェクト、引数)で追加できます。配列またはArgumentsからのすべての真の値と、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"

0

I bind classNamesコンポーネントににインポートCSSモジュールへ。

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

classnames 宣言する能力を与える className宣言的な方法でReact要素ます。

例:

<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

0

私は通常このように使用します:(あなたの場合)

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

JSXとなると、(通常は)いくつかのjsonがあります...ループするより... コンポーネントmapに加えて、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" ....マップの値に応じて...


0

さまざまなクラスがたくさんあるとき、次のものが役立つことがわかりました。

フィルターはすべてのnull値を削除し、結合は残りのすべての値をスペースで区切られた文字列に入れます。

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

<button className={buttonClasses} onClick={onClick} disabled={disabled ? disabled : false}>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.