ReactJS 컴포넌트에 여러 클래스를 추가하는 방법


347

ReactJS와 JSX를 처음 사용하고 아래 코드에 약간의 문제가 있습니다.

className각 속성에 여러 클래스를 추가하려고합니다 li.

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

여기에서 breif 답변을 찾았습니다. stackoverflow.com/a/36209517/4125588 , JavaScript를 사용하여 정적 또는 동적으로 '+'연산자를 사용하여 정적 또는 동적 클래스를 조인하십시오. HTML의 클래스는 'ab c'와 같아야하며 그 사이에도 공백이 있어야합니다.
Fadeoc Khaos


1
왜 안 classNames={{foo: true, bar: true, baz: false}}하고 classNames={["foo", "bar"]}그냥 일을 ?
피터 V. Mørch

답변:


221

내가 사용하는 클래스 이름을 (하지)를 사용하는 클래스를 결정하는 데 필요한 논리의 공정한 금액이있는 경우. 지나치게 간단한 예 :

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

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

즉, 의존성을 포함하지 않으려면 아래에 더 나은 대답이 있습니다.


190
요소에 두 개의 클래스를 추가하기 위해 클래스 이름 라이브러리를 가져와야하는 것은 너무 나쁩니다. (
user959690

4
@ user959690 이것은 예입니다. 이 라이브러리는 이러한 일을 많이 할 때 매우 좋으며 클래스 적용 여부에 대한 복잡한 논리를 가지고 있습니다. 간단한 작업을 수행하는 경우 템플릿을 사용해야하지만 모든 경우가 다르므로 독자는 자신의 작업에 적합한 도구를 선택해야합니다.
Jack

7
@ user959690 이제 Webpackimport classNames from 'classnames' 을 사용할 때 NPM에 의해 설치 되므로 구성 요소에서 사용할 수 있습니다 className={classNames(classes.myFirstClass, classes.mySecondClass)} .
Hooligancat

5
외부 라이브러리를 사용할 필요가 없습니다. 아래 답변을 참조하십시오.
휴 데이비스

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 8

396

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

158
또한 :<input className={`class1 ${class2}`}>
코디으로 Moniz

3
@unyo 의견을 올릴 수 있도록 답변으로 게시하십시오. 너무 가치가 있습니다. 나는 이것처럼 쉬운 것을 1 시간 동안 찾고 있었고, 나는 이것을 설명으로 묻었습니다. 감사합니다.
Souvik Ghosh

결과는 <input class=" form-control input-lg round-lg" />입니다. 처음에 여분의 공간을 기록하십시오. 이것은 유효하지만 못생긴 것입니다. react FAQ에서도 다른 방법을 사용하거나 클래스 이름 패키지를 사용하는 것이 좋습니다. reactjs.org/docs/faq-styling.html
Nakedible

어쨌든보다 효율적이고 깨끗하며 읽기 쉬운 솔루션 인 Vanilla JavaScript를 사용하여 설정할 수있는 클래스를 설정하기 위해 왜 (허용 된 답변에서와 같이) 라이브러리를 가져 오는지 이해할 수 없습니다.
Marcus Parsons

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]}
Doug Wilhelm

1
@ DougWilhelm 나는 그것이 효과가 있다고 생각하지 않습니다. 암시 적으로 toString을 호출하고 쉼표로 구분 된 클래스 목록을 만듭니다. github.com/facebook/react/issues/3138
0xcaff

6
className={[listOfClasses].join(' ')}그것을 사용하는 것이 좋습니다 . 감사합니다!
Ala Eddine JEBALI

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

LOL, 나는 내 머리를 부수고 대답은 간단한 concat입니다 : D. CSS 로더 모듈과 BTW이 alsow 일
GusDeCooL

그것의 문제는 당신이 선택적 클래스를 가질 수 없다는 것입니다 (정의되지 않으면 추가되지 않을 것입니다). 따라서 클래스가 null이 아닌지 (선택적 아님) 확실하지 않습니다. 선택의 경우 classes ()와 같은 도우미가 더 낫지 않습니다. 우리는 className={슬라이더 와 같은 템플릿으로 삼항을 사용할 수 있습니다 $ {className? `$ {className} : ''}}``. 그러나 그것은 많이입니다. [참고 : 'something'+ undefined = '뭔가 정의되지 않은 것'. JS 동적 변환.
Mohamed Allal

물론 위의 변수를 선언하고 조건부로 사용할 수 있습니다 :)
Jamie Hutber

42

ES6 템플릿 리터럴을 사용하면됩니다.

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

1
이 거의 나를 위해 일한은 다음과 같습니다 그래서 난 그냥, 너무 클래스 1과 더 이상 오류를 보간했다 <input className={`${class1} ${class2}`}>
킹스턴 행운을

35

다음과 같이 여러 클래스 이름을 가진 요소를 만들 수 있습니다.

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

당연히 클래스 이름이 포함 된 문자열을 사용하고이 문자열을 조작하여 요소의 클래스 이름을 업데이트 할 수 있습니다.

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

1
이것을 테스트 했습니까? 나는 :)
까마귀

그래, 내가 했어. 실제로, 나는 그것을 자주 사용하고 있지만 오타를보고 수정했습니다. 물론 첫 번째 줄에 클래스 이름을 포함하는 문자열은 "대신에 사용해야 '합니다. 미안합니다.
nightlyop

20

ES6를 사용하여이를 수행 할 수 있습니다.

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

여러 클래스와 조건을 나열 할 수 있으며 정적 클래스를 포함 할 수도 있습니다. 추가 라이브러리를 추가 할 필요는 없습니다.

행운을 빕니다 ;)


2
여분의 공백을 모두 고려하면 HTML이 매우 추악합니다.
Nakedible

2
그런 식으로 쓸 필요는 없습니다. 이것은 솔루션을 더 잘 설명하는 예일뿐입니다. 그리고 항상 생산에 당신은 축소 된 버전 :이
흐리 스토 Eftimov

18

바닐라 JS

외부 라이브러리가 필요하지 않습니다. ES6 템플릿 문자열 만 사용하십시오 .

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

바닐라 JS는 ES6이 아닙니다. 그러나 나는 당신의 모범을 좋아합니다.
RyanNerd

8
@RyanNerd "ES6는 바닐라 JS가 아닙니다"를 의미합니까? 어쨌든 바닐라 js는 프레임 워크가없는 자바 스크립트를 의미하기 때문입니다. ES6은 최신 버전의 자바 스크립트입니다. - stackoverflow.com/a/20435685/5111113
Huw 데이비스

오답은 아니지만 많이 향상 될 수 있습니다. 예를 들어, 다른 모든 사람들은 상태에 대한 예를 추가했습니다.
JGallardo 21

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>

조건부로 클래스를 추가하거나 제거해야하는 경우를위한 두 번째 클래스입니다.


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

사용 페이스 북의 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} />
    )
}

지도에서 동일한 작업을 수행하거나 축소 할 수있는 경우 폐쇄를 사용하는 이유는 무엇입니까? 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]}

기존 답변이 중복되었습니다 .
잭 Bashford

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

모든 형식 (Array, Object, Argument)으로 클래스를 추가 할 수 있습니다. 배열 또는 인수의 모든 진실 값과 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); 

classnamesclassName선언적 방식으로 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을 가지고 있습니다 ... component . 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.