ReactJS Bileşenine birden çok sınıf nasıl eklenir


348

ReactJS ve JSX için yeni ve aşağıdaki kod ile küçük bir sorun yaşıyorum.

classNameHer özniteliğe birden çok sınıf eklemek çalışıyorum li:

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

Benim React bileşenim:

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

Burada bir breif cevap buldum stackoverflow.com/a/36209517/4125588 , sadece bu sınıflara katılmak için JavaScript kullanın, statik veya dinamik, '+' operatörü ile, birinci sınıf dışındaki sınıflardan önce gerçek olarak '' eklemeyi unutmayın HTML'deki sınıf 'ab c' gibi olmalı, aralarında boşluk olmalıdır.
Fadeoc Khaos


1
Neden çalışmıyor classNames={{foo: true, bar: true, baz: false}}ve classNames={["foo", "bar"]}sadece çalışıyor ?
Peter V.Mørch

Yanıtlar:


221

Kullandığım classnames (değil) kullanımına sınıfları karar vermek için gerekli mantık adil bir miktar olduğunda. Çok basit bir örnek :

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

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

Bununla birlikte, bir bağımlılık eklemek istemiyorsanız, aşağıda daha iyi cevaplar vardır.


190
Bir öğeye sadece iki sınıf eklemek için sınıf isimleri kitaplığı getirmeniz çok kötü :(
user959690

4
@ user959690 Bu bir örnektir. Bu kütüphane çok şey yaparken çok güzel ve derslerin ne zaman uygulanıp uygulanmayacağı konusunda karmaşık bir mantığınız var. Basit bir şey yapıyorsanız, sadece şablonları kullanın, ancak her durum farklıdır ve okuyucu işi için doğru aracı seçmelidir.
Jack

7
@ user959690 Webpack'i kullanırken şimdi NPM tarafından yüklendiğini belirtmek gerekir , bu nedenle import classNames from 'classnames'bir bileşende kullanmak için className={classNames(classes.myFirstClass, classes.mySecondClass)} .
Hooligancat

5
Harici bir kitaplık kullanmaya gerek yok, aşağıdaki cevabıma bakın.
Huw Davies

1
Kütüphanenin başka avantajları da var: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

396

Kullandığım ES6 şablon değişmezleri . Örneğin:

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

Ve sonra sadece render et:

<input className={classes} />

Tek katmanlı versiyon:

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

158
Ayrıca:<input className={`class1 ${class2}`}>
Cody Moniz

3
@ unyo Yorumunuzu cevaplayabilmem için lütfen yorumunuzu cevap olarak gönderin. Bunu çok hak ediyor. Bu kadar kolay bir şey için 1 saat arıyordum ve şimdi bunu bir yorum olarak gömülü buluyorum. Teşekkür ederim.
Souvik Ghosh

Bu ile sonuçlanır <input class=" form-control input-lg round-lg" />. Başlangıçta fazladan boşluk bırakın. Bu geçerli, ama çirkin. Hatta tepki SSS başka bir yol veya sınıf adları
Nakedible

Neden daha verimli, daha temiz ve okunabilir bir çözüm olan Vanilla JavaScript kullanılarak ayarlanabilecek bazı sınıfları ayarlamak için bir kütüphaneyi (kabul edilen yanıtta olduğu gibi) neden içe aktaracağınızı anlayamıyorum.
Marcus Parsons

2
Bu doğru cevap. Bunun için "doğru" cevapta önerildiği gibi bir bağımlılık kullanmak aşırıdır.
TheDarkIn1978

171

Sadece JavaScript kullanın.

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

Bir nesneye sınıflara dayalı anahtarlar ve değerler eklemek istiyorsanız aşağıdakileri kullanabilirsiniz:

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

Veya daha da basit:

const isEnabled = true;
const isChecked = false;

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

İşte benim için çalışan hat:className={['terra-Table', medOrder.resource.status]}
Doug Wilhelm

1
@DougWilhelm Bunun işe yaradığını düşünmüyorum. Örtük olarak toString öğesini çağırır ve virgülle ayrılmış sınıflar listesi oluşturur. github.com/facebook/react/issues/3138
0xcaff

6
Kullanmak iyi fikir className={[listOfClasses].join(' ')}benim için çalışıyor teşekkürler!
Ala Eddine JEBALI

98

concat

Fantezi olmaya gerek yok CSS modülleri kullanıyorum ve çok kolay

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

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

Bunun sonucu:

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

Başka bir deyişle, her iki stil

Şartlılar

Aynı fikri if's ile kullanmak kolay olurdu

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

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

1
Bu benim için çalıştı, '-' isimleriyle birlikte, yani: <nav className = {styles.navbar + "" + styles ['navbar-default']}>
Flinkman

LOL, kafamı çatlatıyorum ve cevap basit bir sonuç: D. Btw bu alsow CSS Yükleyici Modülü ile çalışır
GusDeCooL

Buradaki sorun, isteğe bağlı sınıflara sahip olamamanızdır (tanımsızsa, eklenmez), bu nedenle sınıfınızın boş olmadığından (isteğe bağlı değil) emin olmanıza bağlıdır. İsteğe bağlı olarak class () gibi bir yardımcıdan daha iyi olamaz. biz böyle şablonlar ile üçlü kullanabilirsiniz className={{className kaydırıcı $? `$ {className} : ''}}` `. Ama çok fazla. [not: 'bir şey' + undefined = 'yetersiz bir şey'. Js dinamik dönüşüm.
Mohamed Allal

Tabii ki, sadece bir değişken beyan ve şartlı olarak kullanın :)
Jamie Hutber

42

Bu, ES6 şablon değişmezleriyle elde edilebilir:

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

1
Bu neredeyse benim için çalıştı sadece ben de class1 enterpolate ve daha fazla hata yok, bu yüzden böyle görünüyor <input className={`${class1} ${class2}`}>
Kingston Fortune

35

Bunun gibi birden çok sınıf adına sahip bir öğe oluşturabilirsiniz:

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

Doğal olarak, sınıf adlarını içeren bir dize kullanabilir ve öğenin sınıf adlarını güncellemek için bu dizeyi kullanabilirsiniz.

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

1
Bunu test ettin mi?
kuzgun

Evet yaptım. Aslında, oldukça sık kullanıyorum ama sadece bir yazım hatası gördüm ve düzelttim. Tabii ki, ilk satırdaki sınıf adlarını içeren dize "yerine kullanılmalıdır '. Bunun için üzgünüm.
nightlyop

20

ES6 ile bunu şu şekilde yapabilirsiniz:

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

Birden fazla sınıfı ve koşulu listeleyebilir ve ayrıca statik sınıflar ekleyebilirsiniz. Ek bir kütüphane eklemek gerekli değildir.

İyi şanslar ;)


2
Bu, tüm ekstra boşluklar göz önüne alındığında çok çirkin HTML ile sonuçlanır.
Nakedible

2
Böyle yazmak gerekli değildir. Bu sadece çözümü daha iyi açıklayan bir örnektir. Ve her zaman üretimde
minimize edilmiş bir

18

Vanilya JS

Harici kütüphanelere gerek yok - sadece ES6 şablon dizelerini kullanın :

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

Vanilya JS ES6 DEĞİLDİR. Ama senin örneğini beğendim.
RyanNerd

8
@RyanNerd "ES6 vanilya JS değil" anlamına mı geliyor? Her neyse, öyle, çünkü vanilya js, çerçevesiz javascript anlamına geliyor. ES6, javascript'in daha yeni bir sürümüdür. - stackoverflow.com/a/20435685/5111113
Huw Davies

Yanlış bir cevap değil ama çok geliştirilebilir. Örneğin, herkes devletler hakkında örnekler ekledi.
JGallardo

10

Belki sınıf isimleri size yardımcı olabilir.

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

1
Bu örneği daha kullanışlı hale getirebilir misiniz?
JGallardo

9

Sadece birden fazla sınıf eklemek için harici bir paket kullanmamız gerektiğini düşünmüyorum.

Ben şahsen kullanıyorum

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

veya

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

ikincisi, koşullu olarak sınıf eklemeniz veya kaldırmanız gerektiğinde.


1
bu her iki şekilde de sadece bir sınıf ekleyecektir.
TrickOrTreat

6

Sadece ekleyerek, boş dizeleri filtreleyebiliriz.

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

6

Böyle birden fazla sınıf isimleri ile bir öğe oluşturabilirsiniz, ben her iki şekilde denedim, onun iyi çalışıyor ...

Herhangi bir css içe aktarıyorsanız, şu yolu takip edebilirsiniz: Yol 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>
    );
  }
}

yol 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>
    );
  }
}

**

Dahili olarak css uyguluyorsanız:

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

Aşağıdakileri yapabilirsiniz:

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

Kısa ve basit bir çözüm, umarım bu yardımcı olur.



4

Partiye geç, ama neden böyle basit bir sorun için üçüncü taraf kullanıyorsunuz?

@Huw Davies'in bahsettiği gibi yapabilirsin - en iyi yol

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(' ')}

İkiside iyi. Ancak yazma büyük bir uygulama için karmaşık hale gelebilir. Optimal yapmak için yukarıdaki şeyleri aynısını yaparım ama yardımcı bir sınıfa koyarım

Aşağıdaki yardımcı işlevimi kullanarak, gelecekteki düzenleme için mantığı ayrı tutmama izin verir ve ayrıca sınıfları eklemem için birden fazla yol sunar

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

veya

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

Bu benim yardımcı fonksiyonum. Tüm ortak yöntemlerimi sakladığım bir helper.js'ye koydum. Bu kadar basit bir işlev olarak, kontrolü elinde tutmak için 3. tarafı kullanmaktan kaçındım

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

3

Dizileri kullanabilir ve sonra boşluk kullanarak bunlara katılabilirsiniz.

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

Bunun sonucu:

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

3

Bunun geç bir cevap olduğunu biliyorum, ama umarım bu birisine yardım eder.

' Birincil ', ' font-i ', ' font-xl ' css dosyasında aşağıdaki sınıfları tanımladığınızı düşünün

  • İlk adım CSS dosyasını içe aktarmak olacaktır.
  • Sonra

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

hile yapardı!

Daha fazla bilgi için: https://www.youtube.com/watch?v=j5P9FHiBVNo&list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&index=20


3

daha fazla sınıf eklemek için

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

2

Facebook'un TodoTextInput.js örneğini kullanma

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

değiştirilmesi classnames şöyle görünecek düz vanilya js kodu ile:

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

Başka bir modül almak istemiyorsanız, bu işlev classNamesmodül gibi çalışır .

function classNames(rules) {
    var classes = ''

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

    return classes
} 

Bu şekilde kullanabilirsiniz:

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

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

Aynı şeyi harita ile yapabilir veya azaltabiliyorsanız neden kapaklar kullanmalısınız? function classNames(rules) { return Object.entries(rules) .reduce( (arr, [cls, flag]) => { if (flag) arr.push(cls); return arr }, [] ).join(" ") }
Евгений Савичев

1

İşte bu yaptığım şey:

Bileşen:

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

Aranan Bileşen:

<Button className = 'hashButton free anotherClass' />

1

React 16.6.3 ve @Material UI 3.5.1 kullanıyorum ve className benzeri dizileri kullanabiliyor className={[classes.tableCell, classes.capitalize]}

Yani örneğinizde aşağıdakiler benzer olacaktır.

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

Yaptığım şey bu (MUI olmasa da) ve çalışmıyor, sadece birinci sınıfı uygular - uyarı veya şikayet yok.
Juan Lanus

1

Https://www.npmjs.com/package/classnames kullanın

'classnames' öğesinden import classNames;

  1. Ayrılmış koma kullanarak birden fazla sınıf kullanabilir:

    <li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li>
  2. Koşulla ayrılmış komaları kullanarak birden fazla sınıf kullanabilir:

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

Diziyi classNames öğesinin sahne öğesi olarak kullanmak da çalışır, ancak uyarı verir.

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


0

Ben rc-classnames paketi kullanıyorum.

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

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

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

Sınıfları istediğiniz biçimde ekleyebilirsiniz (Dizi, Nesne, Bağımsız Değişken). Dizilerden veya Bağımsız Değişkenlerden gelen tüm doğruluk değerleri artı bir truearaya getirilmeye eşit nesnelerdeki anahtarlar .

Örneğin:

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 classNamesbileşen içine alınan css modülüne.

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

classnamesclassNamebir React öğesi için bildirimsel bir şekilde bildirimde bulunma yeteneği verir .

örn:

<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

Genellikle şu şekilde kullanırım: (senin durumunda)

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

JSX ve (genellikle) söz konusu olduğunda, döngüden daha fazla ... json ... bileşenimiz var . haritasının yanı sıra, JSON'daki özellik değerine bağlı olarak sınıf adını oluşturmak için json özelliğinin var olup olmadığını denetlemek için bazı koşullar. Aşağıdaki örnekte component_color ve component_dark_shade , component.map () öğesinin özellikleridir

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

Çıktı: <div class="component no-color light" .... Veya: <div class="component blue dark" ....haritadaki değerlere bağlı olarak ...


0

Çok çeşitli sınıflarım olduğunda, aşağıdakileri yararlı buldum.

Filtre, nulldeğerlerden herhangi birini kaldırır ve birleştirme kalan tüm değerleri boşlukla ayrılmış bir dizeye koyar.

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

<button className={buttonClasses} onClick={onClick} disabled={disabled ? disabled : false}>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.