web-dev-qa-db-fra.com

Comment ajouter plusieurs classes à un composant ReactJS

Je suis nouveau sur ReactJS et JSX et j'ai un petit problème avec le code ci-dessous. 

J'essaie d'ajouter plusieurs classes à l'attribut className sur chaque li:

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

Mon composant React est:

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

J'utilise classnames . Par exemple:

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

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

J'utilise ES6 _ { modèles littéraux } _. Par exemple:

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

Et puis juste le rendre:

<input className={classes} />

Version monocouche:

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

Il suffit d'utiliser JavaScript.

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

Si vous souhaitez ajouter des clés et des valeurs basées sur des classes dans un objet, vous pouvez utiliser les éléments suivants:

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

Ou encore plus simple:

const isEnabled = true;
const isChecked = false;

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

Concat

Pas besoin d'être chic, j'utilise des modules CSS et c'est facile

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

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

Cela se traduira par:

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

En d'autres termes, les deux styles

63
Jamie Hutber

Cela peut être réalisé avec les littéraux de modèle ES6:

<input className={`class1 ${class2}`}>
24
Cody Moniz

Vous pouvez créer un élément avec plusieurs noms de classe comme ceci:

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

Naturellement, vous pouvez utiliser une chaîne contenant les noms de classe et manipuler cette chaîne pour mettre à jour les noms de classe de l'élément.

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

Voici comment vous pouvez le faire avec ES6:

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

Vous pouvez répertorier plusieurs classes et conditions et vous pouvez également inclure des classes statiques. Il n'est pas nécessaire d'ajouter une bibliothèque supplémentaire.

Bonne chance ;)

15
Hristo Eftimov

Vanilla JS 

Pas besoin de bibliothèques externes - utilisez simplement ES6 template strings :

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

Peut-être que classnames peut vous aider.

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

En ajoutant simplement, nous pouvons filtrer les chaînes vides.

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

En retard à la fête, mais pourquoi utiliser un tiers pour un problème aussi simple?

Vous pouvez le faire comme l'a mentionné @Huw Davies - le meilleur moyen

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

Les deux sont bons. Mais écrire peut devenir complexe pour une grande application. Pour le rendre optimal, je fais la même chose que ci-dessus mais le mets dans une classe d'aide

L’utilisation de la fonction d’aide ci-dessous me permet de garder la logique séparée pour les éditions futures et me donne également plusieurs façons d’ajouter les classes.

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

ou

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

Ceci est ma fonction d'assistance ci-dessous. Je l'ai mis dans un helper.js où je garde toutes mes méthodes communes. Étant une fonction si simple, j’ai évité d’utiliser une tierce partie pour garder le contrôle

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

Je ne pense pas que nous ayons besoin d'utiliser un paquet externe pour simplement ajouter plusieurs classes.

J'utilise personnellement

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

le second au cas où vous auriez besoin d'ajouter ou de supprimer des classes de manière conditionnelle.

Si vous ne souhaitez pas importer un autre module, cette fonction fonctionne comme le module classNames.

function classNames(rules) {
    var classes = ''

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

    return classes
} 

Vous pouvez l'utiliser comme ceci:

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

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

Utilisez https://www.npmjs.com/package/classnames

importer classNames de 'classnames';

  1. Peut utiliser plusieurs classes en utilisant des virgules séparées:

    <li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li>
    
  2. Peut utiliser plusieurs classes en utilisant des virgules séparées avec une condition:

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

Utiliser array en tant que props à classNames fonctionnera également, mais avertit par exemple.

className={[classes.tableCellLabel, classes.tableCell]}
1
Vikramjit Singh

Utilisation de l'exemple TodoTextInput.js de facebook

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

le remplacement de classnames par du code plain Vanilla js ressemblera à ceci:

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} />
    )
  }
1
Vlad Bezden

Vous pouvez créer un élément avec plusieurs noms de classe comme celui-ci, j'ai essayé ces deux méthodes, cela fonctionne bien ...

Si vous importez n'importe quel css, vous pouvez suivre cette voie: Voie 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>
    );
  }
}

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

**

Si vous appliquez css en interne:

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>
0
arvinda kumar

bindclassNames au module css importé dans le composant.

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

classnames donne la possibilité de déclarer className pour un élément React de manière déclarative.

ex: 

<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

J'utilise React 16.6.3 et @Material UI 3.5.1 et peux utiliser des tableaux dans className comme className={[classes.tableCell, classes.capitalize]}

Donc, dans votre exemple, ce qui suit serait similaire.

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

pour plus de classes en ajoutant, className = {${classes.hello} ${classes.hello1}

0
Rama Krishna

C'est ce que je fais:

Composant:

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

Composant appelant:

<Button className = 'hashButton free anotherClass' />
0
RegarBoy

J'utilise rc-classnames package. 

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

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

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

Vous pouvez ajouter des classes dans n'importe quel format (Array, Object, Argument). Toutes les valeurs de vérité des tableaux ou des arguments plus les clés dans les objets égaux à true sont fusionnées. 

par exemple:

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
morajabi