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 & Support <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"));
J'utilise classnames . Par exemple:
...
var liClasses = classNames({
'main-class': true,
'activeClass': self.state.focused === index
});
return (<li className={liClasses}>{data.name}</li>);
...
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'}`} />
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'} />
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
Cela peut être réalisé avec les littéraux de modèle ES6:
<input className={`class1 ${class2}`}>
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>
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 ;)
Pas besoin de bibliothèques externes - utilisez simplement ES6 template strings :
<i className={`${styles['foo-bar-baz']} fa fa-user fa-2x`}/>
Peut-être que classnames peut vous aider.
var classNames = require('classnames');
classNames('foo', {'xx-test': true, bar: false}, {'ox-test': false}); // => 'foo xx-test'
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(' ')}
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 ''
}
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} />
)
}
Utilisez https://www.npmjs.com/package/classnames
importer classNames de 'classnames';
Peut utiliser plusieurs classes en utilisant des virgules séparées:
<li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li>
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]}
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} />
)
}
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>
bind
classNames
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
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>
pour plus de classes en ajoutant, className = {${classes.hello} ${classes.hello1}
C'est ce que je fais:
Composant:
const Button = ({ className }) => (
<div className={ className }> </div>
);
Composant appelant:
<Button className = 'hashButton free anotherClass' />
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"