ReactJS adiciona classe dinâmica a nomes de classe manuais

158

Eu preciso adicionar uma classe dinâmica a uma lista de classes regulares, mas não tenho idéia de como (estou usando babel), algo como isto:

<div className="wrapper searchDiv {this.state.something}">
...
</div>

Alguma ideia?

Mankind1023
fonte
Respostas úteis para as melhores práticas reactjs de styling na ligação
Rahil Ahmad

Respostas:

240

Você pode fazer isso, JavaScript normal:

className={'wrapper searchDiv ' + this.state.something}

ou a versão do modelo de string, com reticulares:

className={`wrapper searchDiv ${this.state.something}`}

É claro que ambos os tipos são apenas JavaScript, mas o primeiro padrão é o tipo tradicional.

De qualquer forma, no JSX, tudo o que estiver entre colchetes é executado como JavaScript, para que você possa basicamente fazer o que quiser lá. Mas combinar seqüências de caracteres JSX e colchetes não é obrigatório para atributos.

dannyjolie
fonte
e o que no caso de várias classes?
Pardeep Jain
5
No caso de várias classes dinâmicas, todas as classes dinâmicas devem ser provenientes do estado, ou seja, não é possível usar element.classList.add("my-class"); permitindo, portanto:className={`wrapper searchDiv ${this.state.something ? "my-class " : ""} ${this.state.somethingElse ? "my-other-class " : ""}`}
Kevin Farrugia
className={'wrapper searchDiv} + this.state.isTrue ? 'my-class' : ' 'Isso não funciona. Alguém pode dizer o porquê?
Kryptokinght
54

Dependendo de quantas classes dinâmicas você precisa adicionar à medida que seu projeto cresce, provavelmente vale a pena conferir o utilitário classnames de JedWatson no GitHub. Ele permite que você represente suas classes condicionais como um objeto e retorna as que são avaliadas como verdadeiras.

Então, como um exemplo da documentação do React:

render () {

var btnClass = classNames({
  'btn': true,
  'btn-pressed': this.state.isPressed,
  'btn-over': !this.state.isPressed && this.state.isHovered
});

return <button className={btnClass}>I'm a button!</button>;

} 

Como o React aciona uma nova renderização quando há uma alteração de estado, os nomes de classes dinâmicas são manipulados naturalmente e atualizados com o estado do seu componente.

Brad Colthurst
fonte
5
O uso de classNames para uma coisa tão simples é um exagero. Evite usá-lo e opte pela resposta simples de dannyjolie
check
2
Tem certeza de que é uma coisa simples? Quase sempre, você deseja ter um controle total de baixa granularidade sobre quais classes são aplicadas aos elementos.
Dragas 26/06
5
@checklist Eu diria o contrário, o pacote classnames é 1.1kB antes do Gzipping (e meio kB depois do Gzipping), não tem dependências e fornece uma API muito mais limpa para a manipulação do nome da classe. Não há necessidade de otimizar prematuramente algo tão pequeno, quando a API é muito mais expressiva. Ao usar a manipulação de seqüência de caracteres padrão, lembre-se de considerar o espaçamento, antes de cada nome de classe condicional ou após cada nome de classe padrão.
Tomhughes
classNames é ótimo, achei que ler, adicionar e corrigir adereços eram mais fáceis do que a manipulação manual, pois o componente aumentava em complexidade.
MiFiHiBye
37

Uma simples sintaxe possível será:

<div className={`wrapper searchDiv ${this.state.something}`}>
oligopol
fonte
25

Aqui está a melhor opção para o className dinâmico, basta fazer uma concatenação como fazemos em Javascript.

     className={
        "badge " +
        (this.state.value ? "badge-primary " : "badge-danger ") +
        " m-4"
      }
Saad Mirza
fonte
Esta é a melhor solução sem problemas de fiapos. Funcionou como um encanto. Obrigado.
Royal.O
3

Se você precisar de nomes de estilo que devem aparecer de acordo com a condição de estado, prefiro usar esta construção:

<div className={'wrapper searchDiv' + (this.state.something === "a" ? " anotherClass" : "")'}>
Sergey Gubarev
fonte
2

tente isso usando ganchos:

        const [dynamicClasses, setDynamicClasses] = React.useState([
    "dynamicClass1", "dynamicClass2
]);

e adicione isso no atributo className:

<div className=`wrapper searchDiv ${[...dynamicClasses]}`>
...
</div>

para adicionar classe:

    const addClass = newClass => {
       setDynamicClasses([...dynamicClasses, newClass])
    }

para excluir a classe:

        const deleteClass= classToDelete => {

           setDynamicClasses(dynamicClasses.filter(class = > {
             class !== classToDelete
           }));

        }
Hamza Khattabi
fonte
1

Você pode usar este pacote npm. Ele lida com tudo e tem opções para classes estáticas e dinâmicas com base em uma variável ou uma função.

// Support for string arguments
getClassNames('class1', 'class2');

// support for Object
getClassNames({class1: true, class2 : false});

// support for all type of data
getClassNames('class1', 'class2', ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames({class1: true, class2 : false})} />
Tushar Sharma
fonte
1
getBadgeClasses() {
    let classes = "badge m-2 ";
    classes += (this.state.count === 0) ? "badge-warning" : "badge-primary";
    return classes;
}

<span className={this.getBadgeClasses()}>Total Count</span>
Harshvardhan Singh Baghel
fonte
-1
className={css(styles.mainDiv, 'subContainer')}

Esta solução é experimentada e testada no React SPFx.

Adicione também a declaração de importação:

import { css } from 'office-ui-fabric-react/lib/Utilities';
Harjot Singh
fonte