ReactJS dodaje klasę dynamiczną do ręcznych nazw klas

158

Muszę dodać klasę dynamiczną do listy zwykłych klas, ale nie mam pojęcia, jak (używam babel), coś takiego:

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

Jakieś pomysły?

Ludzkość1023
źródło
Przydatne odpowiedzi na temat najlepszych praktyk stylizacji Reactjs pod linkiem
Rahil Ahmad

Odpowiedzi:

241

Możesz to zrobić, zwykły JavaScript:

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

lub wersja szablonu napisów, z odwrotnymi znakami:

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

Oba typy to oczywiście tylko JavaScript, ale pierwszy wzorzec jest typem tradycyjnym.

W każdym razie w JSX wszystko, co jest zawarte w nawiasach klamrowych, jest wykonywane jako JavaScript, więc możesz w zasadzie robić tam, co chcesz. Jednak łączenie ciągów JSX i nawiasów klamrowych nie jest rozwiązaniem dla atrybutów.

dannyjolie
źródło
a co w przypadku wielu zajęć?
Pardeep Jain
5
W przypadku wielu klas dynamicznych wszystkie klasy dynamiczne muszą pochodzić ze stanu, czyli nie można ich użyć element.classList.add("my-class"); w związku z tym pozwalając na:className={`wrapper searchDiv ${this.state.something ? "my-class " : ""} ${this.state.somethingElse ? "my-other-class " : ""}`}
Kevin Farrugia
className={'wrapper searchDiv} + this.state.isTrue ? 'my-class' : ' 'To nie działa. Czy ktoś może powiedzieć, dlaczego?
kryptokinght
54

W zależności od tego, ile dynamiczne zajęcia trzeba dodać jako projekt rośnie to chyba warto sprawdzić na classnames użyteczności przez JedWatson na GitHub. Umożliwia reprezentowanie klas warunkowych jako obiektu i zwraca te, które dają wartość true.

A więc jako przykład z dokumentacji Reacta:

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>;

} 

Ponieważ React wyzwala ponowne renderowanie, gdy następuje zmiana stanu, dynamiczne nazwy klas są obsługiwane w naturalny sposób i aktualizowane zgodnie ze stanem komponentu.

Brad Colthurst
źródło
5
Używanie nazw klas do tak prostej rzeczy to przesada. Unikaj korzystania z niego i wybierz prostą odpowiedź dannyjolie
lista kontrolna
2
Czy na pewno to prosta rzecz? Prawie zawsze chcesz mieć pełną kontrolę nad tym, jakie klasy są stosowane do elementów.
Dragas
5
@checklist W przeciwnym razie argumentowałbym, że pakiet nazw klas ma 1,1 kB przed Gzipping (i pół kB po Gzipping), nie ma żadnych zależności i zapewnia znacznie czystsze API do manipulacji nazwami klas. Nie ma potrzeby przedwczesnej optymalizacji czegoś tak małego, gdy API jest znacznie bardziej wyraziste. Używając standardowych operacji na łańcuchach, należy pamiętać o uwzględnieniu odstępów, albo przed każdą nazwą klasy warunkowej, albo po każdej standardowej nazwie klasy.
tomhughes
classNames jest świetne, odkryłem, że czytanie, dodawanie i naprawianie rekwizytów było łatwiejsze niż ręczne manipulowanie, gdy komponent stawał się coraz bardziej złożony.
MiFiHiBye
37

Prosta możliwa składnia to:

<div className={`wrapper searchDiv ${this.state.something}`}>
oligopol
źródło
25

Oto najlepsza opcja dla Dynamic className, po prostu zrób kilka konkatenacji, tak jak robimy to w Javascript.

     className={
        "badge " +
        (this.state.value ? "badge-primary " : "badge-danger ") +
        " m-4"
      }
Saad Mirza
źródło
To najlepsze rozwiązanie bez problemów z kłaczkami. Działał jak urok. Dziękuję Ci.
Royal.
3

Jeśli potrzebujesz nazw stylów, które powinny pojawić się zgodnie ze stanem, wolę użyć tej konstrukcji:

<div className={'wrapper searchDiv' + (this.state.something === "a" ? " anotherClass" : "")'}>
Sergey Gubarev
źródło
2

spróbuj tego, używając haków:

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

i dodaj to w atrybucie className:

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

dodać klasę:

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

aby usunąć zajęcia:

        const deleteClass= classToDelete => {

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

        }
Hamza Khattabi
źródło
1

Możesz użyć tego pakietu npm. Obsługuje wszystko i ma opcje klas statycznych i dynamicznych opartych na zmiennej lub funkcji.

// 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
źródło
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
źródło
-1
className={css(styles.mainDiv, 'subContainer')}

To rozwiązanie zostało wypróbowane i przetestowane w React SPFx.

Dodaj również instrukcję importu:

import { css } from 'office-ui-fabric-react/lib/Utilities';
Harjot Singh
źródło