javascript - practicas - Cómo agregar múltiples clases a un componente ReactJS
react estados (21)
Concat
No es necesario ser elegante. Estoy usando módulos CSS y es fácil.
import style from ''/css/style.css'';
<div className={style.style1+ '' '' + style.style2} />
Esto resultará en:
<div class="src-client-css-pages-style1-selectionItem src-client-css-pages-style2">
En otras palabras, ambos estilos
Condicionales
Sería fácil usar la misma idea con if''s
const class1 = doIHaveSomething ? style.style1 : ''backupClass'';
<div className={class1 + '' '' + style.style2} />
Soy nuevo en ReactJS y JSX y tengo un pequeño problema con el código a continuación.
Estoy tratando de agregar varias clases al atributo
className
en cada
li
:
<li key={index} className={activeClass, data.class, "main-class"}></li>
Mi componente Reaccionar es:
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"));
Vanilla JS
No necesita bibliotecas externas: solo use cadenas de plantilla ES6:
<i className={`${styles[''foo-bar-baz'']} fa fa-user fa-2x`}/>
Así es como puedes hacer eso con ES6:
className = {`
text-right
${itemId === activeItemId ? ''active'' : ''''}
${anotherProperty === true ? ''class1'' : ''class2''}
`}
Puede enumerar múltiples clases y condiciones y también puede incluir clases estáticas. No es necesario agregar una biblioteca adicional.
Buena suerte ;)
Eso es lo que hago:
Componente:
const Button = ({ className }) => (
<div className={ className }> </div>
);
Componente de llamada:
<Button className = ''hashButton free anotherClass'' />
Esto se puede lograr con los literales de plantilla ES6:
<input className={`class1 ${class2}`}>
Estoy usando React 16.6.3 y @Material UI 3.5.1, y puedo usar matrices en className como
className={[classes.tableCell, classes.capitalize]}
Entonces, en su ejemplo, lo siguiente sería similar.
<li key={index} className={[activeClass, data.class, "main-class"]}></li>
No creo que necesitemos usar un paquete externo para solo agregar varias clases.
Yo personalmente uso
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} />
)
}
el segundo en caso de que necesite agregar o eliminar clases condicionalmente.
Puede crear un elemento con varios nombres de clase como este, lo intenté en ambos sentidos, funciona bien ...
Si importa cualquier CSS, puede seguir este camino: Modo 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>
);
}
}
camino 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 aplica css como interno:
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>
Puede crear un elemento con varios nombres de clase como este:
<li className="class1 class2 class3">foo</li>
Naturalmente, puede usar una cadena que contenga los nombres de clase y manipular esta cadena para actualizar los nombres de clase del elemento.
var myClassNammes = ''class1 class2 class3'';
...
<li className={myClassNames}>foo</li>
Si no desea importar otro módulo, esta función funciona como el módulo
classNames
.
function classNames(rules) {
var classes = ''''
Object.keys(rules).forEach(item => {
if (rules[item])
classes += (classes.length ? '' '' : '''') + item
})
return classes
}
Puedes usarlo así:
render() {
var classes = classNames({
''storeInfoDiv'': true,
''hover'': this.state.isHovered == this.props.store.store_id
})
return (
<SomeComponent style={classes} />
)
}
Solo agregando, podemos filtrar cadenas vacías.
className={[
''read-more-box'',
this.props.className,
this.state.isExpanded ? ''open'' : ''close'',
].filter(x => !!x).join('' '')}
Solo usa JavaScript.
<li className={[activeClass, data.klass, "main-class"].join('' '')} />
Si desea agregar claves y valores basados en clases en un objeto, puede usar lo siguiente:
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} />
O incluso más simple:
const isEnabled = true;
const isChecked = false;
<li className={[isEnabled && ''enabled'', isChecked && ''checked'']
.filter(e => !!e)
.join('' '')
} />
// Output:
// <li className={''enabled''} />
Tal vez los classnames pueden ayudarte.
var classNames = require(''classnames'');
classNames(''foo'', {''xx-test'': true, bar: false}, {''ox-test'': false}); // => ''foo xx-test''
Tarde a la fiesta, pero ¿por qué usar un tercero para un problema tan simple?
Podrías hacerlo como mencionó @Huw Davies: la mejor manera
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('' '')}
Ambos son buenos. Pero escribir puede volverse complejo para una aplicación grande. Para hacerlo óptimo, hago lo mismo arriba pero lo pongo en una clase auxiliar
El uso de mi función de ayuda a continuación, me permite mantener la lógica separada para futuras ediciones, y también me brinda múltiples formas de agregar las clases
classNames(styles[''foo-bar-baz], ''fa fa-user'', ''fa-2x'')
o
classNames([styles[''foo-bar-baz], ''fa fa-user'', ''fa-2x''])
Esta es mi función de ayuda a continuación. Lo puse en un helper.js donde guardo todos mis métodos comunes. Al ser una función tan simple, evité usar un tercero para mantener el control
export function classNames (classes) {
if(classes && classes.constructor === Array) {
return classes.join('' '')
} else if(arguments[0] !== undefined) {
return [...arguments].join('' '')
}
return ''''
}
Usando el ejemplo de Facebook TodoTextInput.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} />
)
}
Reemplazar los nombres de clase con código simple vanilla js se verá así:
<li className={`li active`}>Stacy</li>
or <li className={`li ${this.state.isActive ? ''active'' : ''''}`}>Stacy<li>
Use https://www.npmjs.com/package/classnames
importar classNames desde ''nombres de clase'';
-
Puede usar múltiples clases usando comas separadas:
<li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li>
-
Puede usar múltiples clases usando comas separadas con condición:
<li className={classNames(classes.buttonArea, !nodes.length && classes.buttonAreaHidden)}>Hello World</li>
El uso de array como accesorios para classNames también funcionará, pero da una advertencia, por ejemplo
className={[classes.tableCellLabel, classes.tableCell]}
Yo uso el paquete 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
})} />
Puede agregar clases en cualquier formato (matriz, objeto, argumento).
Todos los valores verdaderos de matrices o argumentos más claves en objetos que son iguales a
true
se fusionan.
por ejemplo:
ReactClassNames(''a'', ''b'', ''c'') // => "a b c"
ReactClassNames({ ''a'': true, ''b'': false, c: ''true'' }) // => "a c"
ReactClassNames(undefined, null, ''a'', 0, ''b'') // => "a b"
Yo uso los
literales de plantilla
ES6
.
Por ejemplo:
const error = this.state.valid ? '''' : ''error''
const classes = `form-control round-lg ${error}`
Y luego solo renderízalo:
<input className={classes} />
Versión de una línea:
<input className={`form-control round-lg ${this.state.valid ? '''' : ''error''}`} />
Yo uso los classnames . Por ejemplo:
...
var liClasses = classNames({
''main-class'': true,
''activeClass'': self.state.focused === index
});
return (<li className={liClasses}>{data.name}</li>);
...
para agregar más clases, className = {
${classes.hello} ${classes.hello1}
bind
classNames
al módulo css importado al componente.
import classNames from ''classnames'';
import * as styles from ''./[STYLES PATH];
const cx = classNames.bind(styles);
classnames
ofrece la capacidad de declarar
className
para un elemento React de forma declarativa.
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