Búsqueda de sitios web

javascript - Aplicando condicionalmente atributos de clase en React


Quiero mostrar y ocultar condicionalmente este grupo de botones dependiendo de lo que se pase desde el componente padre, que se ve así:

    <TopicNav showBulkActions={this.__hasMultipleSelected} />

    __hasMultipleSelected: function() {
      return false; //return true or false depending on data
    }
    var TopicNav = React.createClass({
    render: function() {
    return (
        <div className="row">
            <div className="col-lg-6">
                <div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">
                    <button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
                      Bulk Actions <span className="caret"></span>
                    </button>
                    <ul className="dropdown-menu" role="menu">
                      <li><a href="#">Merge into New Session</a></li>
                      <li><a href="#">Add to Existing Session</a></li>
                      <li className="divider"></li>
                      <li><a href="#">Delete</a></li>
                    </ul>
                </div>
            </div>
        </div>
        );
      }
    });

Sin embargo, no está pasando nada con el {this.props.showBulkActions ? 'show' : 'hidden'}. ¿Estoy haciendo algo mal aquí?

Respuesta #1

Las llaves rizadas están dentro de la cadena, por lo que se está evaluando como cadena. Necesitan estar afuera, así que esto debería funcionar:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? 'show' : 'hidden')}>

Nota el espacio después de "pull-right". No quieres proporcionar accidentalmente la clase "pull-rightshow" en lugar de "pull-right show". Además, los paréntesis deben estar allí.

Respuesta #2

Como otros han comentado, la utilidad classnames es el enfoque actualmente recomendado para manejar nombres de clases CSS condicionales en ReactJs.

En su caso, la solución se verá así:

var btnGroupClasses = classNames(
  'btn-group',
  'pull-right',
  {
    'show': this.props.showBulkActions,
    'hidden': !this.props.showBulkActions
  }
);

...

<div className={btnGroupClasses}>...</div>

Como nota al margen, te sugeriría que intentaras evitar usar tanto las clases show como hidden, para que el código pueda ser más sencillo. Lo más probable es que no necesites establecer una clase para que algo se muestre por defecto.

Apéndice 2021: para mejorar el rendimiento, puedes considerar clsx como una alternativa.

Respuesta #3

Si estás usando un transpiler (como Babel o Traceur) puedes usar las nuevas "cadenas de plantilla" de ES6.

Aquí está la respuesta de @spitfire109, modificada en consecuencia:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>

Este enfoque te permite hacer cosas geniales como esa, renderizando ya sea s-is-shown o s-is-hidden:

<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>

Respuesta #4

puedes simplemente hacer lo siguiente, por ejemplo.

let classNameDependsOnCondtion = i18n.language == 'en' ? "classname" : "";

className={`flex flex-col lg:flex-row list-none ${classNameDependsOnCondtion }`}

O

className={`flex flex-col lg:flex-row list-none ${i18n.language == 'en' ? "classname" : ""}`}

Respuesta #5

Puedes usar aquí literales de cadena

const Angle = ({show}) => {

   const angle = `fa ${show ? 'fa-angle-down' : 'fa-angle-right'}`;

   return <i className={angle} />
}

Respuesta #6

Reemplazar :

<div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">`

con :

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}

Respuesta #7

En caso de que solo necesites un nombre de clase opcional:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? "show" : "")}>

Respuesta #8

Ampliando la excelente respuesta de @spitfire109, uno podría hacer algo como esto:

rootClassNames() {
  let names = ['my-default-class'];
  if (this.props.disabled) names.push('text-muted', 'other-class');

  return names.join(' ');
}

y luego dentro de la función render:

<div className={this.rootClassNames()}></div>

mantiene el jsx corto

Respuesta #9

O usa npm classnames. Es muy fácil y útil, especialmente para construir la lista de clases

Respuesta #10

Puedes usar arrays de ES6 en lugar de classnames. La respuesta se basa en el artículo del Dr. Axel Rauschmayer: Agregar entradas condicionalmente dentro de literales de Array y objeto.

<div className={[
                 "classAlwaysPresent", 
                 ...Array.from(condition && ["classIfTrue"])
                ].join(" ")} />

Respuesta #11

Dos mil diecinueve

React es como un lago de muchas utilidades. Pero no necesitas ningún paquete npm para eso. Solo crea en algún lugar la función classnames y llámala cuando la necesites;

function classnames(obj){
  return Object.entries(obj).filter( e => e[1] ).map( e=>e[0] ).join(' ');
}

o

function classnames(obj){
 return Object.entries(obj).map( ([cls,enb]) => enb? cls: '' ).join(' ');
}

ejemplo

  stateClass= {
    foo:true,
    bar:false,
    pony:2
  }
  classnames(stateClass) // return 'foo pony'

 <div className="foo bar {classnames(stateClass)}"> some content </div>

Solo para inspiración

declarando un elemento DOM auxiliar y usando su método nativo toggle:

(DOMTokenList)classList.toggle(class,condition)

ejemplo :

const classes = document.createElement('span').classList; 

function classstate(obj){
  for( let n in obj) classes.toggle(n,obj[n]);
 return classes; 
}
 

Respuesta #12

<div className={['foo', condition && 'bar'].filter(Boolean).join(' ')} />

.filter(Boolean) elimina los valores "falsos" del array. Dado que los nombres de clase deben ser cadenas, cualquier cosa diferente de eso no se incluiría en el nuevo array filtrado.

console.log(  ['foo', true  && 'bar'].filter(Boolean).join(' ')  )
console.log(  ['foo', false && 'bar'].filter(Boolean).join(' ')  )

Arriba escrito como una función:

const cx = (...list) => list.filter(Boolean).join(' ')

// usage:
<div className={cx('foo', condition && 'bar')} />

var cx = (...list) => list.filter(Boolean).join(' ')
console.log(  cx('foo', 1 && 'bar', 1 && 'baz')  )
console.log(  cx('foo', 0 && 'bar', 1 && 'baz')  )
console.log(  cx('foo', 0 && 'bar', 0 && 'baz')  )

Respuesta #13

simplemente usa este enfoque--

<div className={`${this.props.showActions ? 'shown' : 'hidden'}`}>

esto es mucho más ordenado y limpio.

Artículos relacionados