Reaguj J warunkowo stosując atrybuty klasy


333

Chcę warunkowo wyświetlić i ukryć tę grupę przycisków w zależności od tego, co jest przekazywane z komponentu nadrzędnego, który wygląda następująco:

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

Nic się jednak nie dzieje z {this.props.showBulkActions? 'Pokaż ukryte'}. Czy robię tu coś złego?


Możesz również rozważyć użycie opcji ładowania początkowego , ponieważ to abstrakuje niektóre elementy klasy we właściwościach składników, dzięki czemu to, co próbujesz zrobić, jest nieco łatwiejsze.
Dancrumb

Odpowiedzi:


588

Nawiasy klamrowe znajdują się wewnątrz ciągu, więc jest on oceniany jako ciąg. Muszą być na zewnątrz, więc to powinno działać:

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

Zwróć uwagę na spację po „przeciągnięciu w prawo”. Nie chcesz przypadkowo podać klasy „pull-righthow” zamiast „pull-right show”. Tam też muszą być nawiasy.


3
Dzięki! Musiałem go nieco zmodyfikować, ponieważ z jakiegoś powodu w ogóle nie wyświetlało się w prawo btn-group. Po prostu pokaż lub ukryj.
apexdodge

Jest to szczególnie pomocne w niektórych przypadkach, w których classnamesmoże nie być właściwe. Jeśli jesteś w swojej renderfunkcji i masz map, możesz wiedzieć tylko, czy chcesz dodać klasę podczas jej renderowania, więc ta odpowiedź jest do tego bardzo przydatna.
Dave Cooper

świetna alternatywa zamiast posiadania zestawu szablonów warunkowych w renderowaniu lub powrocie
devonj

@apexdodge, jaką modyfikację musiałeś wykonać. Mam ten sam problem.
RamY

1
@RamY Jednym ze sposobów jest umieszczenie wszystkich klas w warunkowym this.props.showBulkActions ? 'btn-group pull-right show' : 'btn-group pull-right hidden'). Nie elegancki, ale działa.
Ian

87

Jak skomentowali inni, narzędzie classnames jest obecnie zalecanym podejściem do obsługi warunkowych nazw klas CSS w ReactJs.

W twoim przypadku rozwiązanie będzie wyglądać następująco:

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

...

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

Na marginesie, sugeruję, abyś starał się unikać używania obu klas showi hiddenklas, aby kod był prostszy. Najprawdopodobniej nie musisz ustawiać klasy, aby coś pokazywało się domyślnie.


11
Czy mógłbyś rozwinąć narzędzie classNames będące „obecnie zalecanym podejściem”? Czy jest to zapisane gdzieś w dobrze cenionym dokumencie najlepszych praktyk? A może po prostu słowo mówione wokół React i classNamesw tej chwili?
Alexander Nied

6
@ towarzyszył W momencie pisania tego dokumentu był zalecany w oficjalnej dokumentacji React: web.archive.org/web/20160602124910/http://facebook.github.io:80/…
Diego V

3
W najnowszej dokumentacji wciąż wspomniano : „ Jeśli często piszesz taki kod, pakiet classnames może go uprościć
Franklin Yu

66

Jeśli używasz transpilatora (takiego jak Babel lub Traceur), możesz użyć nowych „ ciągów szablonów ” ES6 .

Oto odpowiedź @ spitfire109, odpowiednio zmodyfikowana:

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

Takie podejście pozwala na wykonywanie schludne rzeczy tak, rendering albo s-is-shownalbo s-is-hidden:

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

20
Zachowaj ostrożność przy drugim podejściu, szczególnie w dużych bazach kodowych, ponieważ powoduje to, że łańcuchy klas są mniej zrozumiałe. Na przykład, jeśli ktoś szuka s-is-shownlub s-is-hiddenw bazie kodu, nie znajdzie tego kodu.
zaznacz

15

Możesz użyć tutaj literałów ciągowych

const Angle = ({show}) => {

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

   return <i className={angle} />
}

9

Spoglądając na dobrą odpowiedź @ spitfire109, można zrobić coś takiego:

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

  return names.join(' ');
}

a następnie w ramach funkcji renderowania:

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

utrzymuje jsx krótki


8

Lub użyj nazw klas npm . Jest to bardzo łatwe i przydatne, zwłaszcza przy tworzeniu listy klas


8

Jeśli potrzebujesz tylko jednej opcjonalnej nazwy klasy:

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

1
To doda falseklasę, gdy warunek się nie powiedzie.
RA.


5

2019:

React jest jezioro wiele narzędzi. Ale nie potrzebujesz npmdo tego żadnej paczki. po prostu stwórz gdzieś funkcję classnamesi wywołaj ją, kiedy będziesz potrzebować;

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

lub

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

przykład

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

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

Tylko dla inspiracji

Element stwierdzenie pomocniczych i wykorzystywane togglemetody

(DOMToken​List)classList.toggle(class,condition)

przykład:

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

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

4

Bardziej eleganckie rozwiązanie, które jest lepsze pod względem konserwacji i czytelności:

const classNames = ['js-btn-connect'];

if (isSelected) { classNames.push('is-selected'); }

<Element className={classNames.join(' ')}/>

3

możesz użyć tego:

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

2

To by działało dla ciebie

var TopicNav = React.createClass({
render: function() {

let _myClasses = `btn-group pull-right {this.props.showBulkActions?'show':'hidden'}`;

return (
            ...
            <div className={_myClasses}>
               ...
            </div>
    );
  }
});

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', null, undefined, 3, ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames('show', {class1: true, class2 : false})} /> // "show class1"

1

W this.props.showBulkActionszależności od wartości możesz dynamicznie przełączać klasy w następujący sposób.

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

1

Chciałbym dodać, że możesz również używać zmiennej treści jako części klasy

<img src={src} alt="Avatar" className={"img-" + messages[key].sender} />

Kontekstem jest rozmowa między botem a użytkownikiem, a style zmieniają się w zależności od nadawcy, oto wynik przeglądarki:

<img src="http://imageurl" alt="Avatar" class="img-bot">

1

Jest to przydatne, gdy masz więcej niż jedną klasę do dołączenia. Możesz dołączyć do wszystkich klas w tablicy ze spacją.

const visibility = this.props.showBulkActions ? "show" : ""
<div className={["btn-group pull-right", visibility].join(' ')}>

1

Zastąpić:

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

z:

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

0

Odniesienie do odpowiedzi ogniowej @split, możemy ją zaktualizować o literały szablonów, które są bardziej czytelne, dla odniesienia Literatura szablonu javascript

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

0

Znalazłem to, co wyjaśnia, jak to zrobić za pomocą trójki i Biblioteki Classnames

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.