Bereaksi Js menerapkan atribut kelas secara kondisional


334

Saya ingin memperlihatkan dan menyembunyikan grup tombol ini secara kondisional tergantung pada apa yang diteruskan dari komponen induk yang terlihat seperti ini:

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

Namun tidak ada yang terjadi, dengan {this.props.showBulkActions? 'show': 'hidden'}. Apakah saya melakukan sesuatu yang salah di sini?


Anda mungkin juga ingin mempertimbangkan react-bootstrap , karena ini mengabstraksi beberapa hal kelas menjadi properti komponen, membuat apa yang Anda coba lakukan menjadi sedikit lebih mudah.
Dancrumb

Jawaban:


591

Kurung kurawal berada di dalam string, sehingga dievaluasi sebagai string. Mereka harus berada di luar, jadi ini harus bekerja:

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

Perhatikan spasi setelah "tarik-kanan". Anda tidak ingin secara tidak sengaja memberikan kelas "pull-rightshow" alih-alih "pull-right show". Juga tanda kurung harus ada di sana.


3
Terima kasih! Saya harus memodifikasinya sedikit karena untuk beberapa alasan itu tidak menghasilkan btn-group pull-right sama sekali. Hanya perlihatkan atau sembunyikan.
Apexdodge

Ini sangat membantu dalam kasus-kasus tertentu di mana classnamesmungkin tidak sesuai. Jika Anda berada dalam renderfungsi Anda dan Anda memiliki map, Anda mungkin hanya tahu apakah Anda ingin menambahkan kelas pada saat Anda merendernya, jadi jawaban ini cukup berguna untuk itu.
Dave Cooper

alternatif yang bagus alih-alih memiliki banyak template bersyarat dalam membuat atau mengembalikan
devonj

@apexdodge modifikasi apa yang harus Anda lakukan. Saya memiliki masalah yang sama.
RamY

1
@RamY Salah satu caranya adalah dengan meletakkan semua kelas di dalam kondisi this.props.showBulkActions ? 'btn-group pull-right show' : 'btn-group pull-right hidden'). Tidak elegan tapi berhasil.
Ian

87

Seperti orang lain berkomentar, utilitas classnames adalah pendekatan yang saat ini direkomendasikan untuk menangani nama kelas CSS bersyarat di ReactJs.

Dalam kasus Anda, solusinya akan terlihat seperti:

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

...

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

Sebagai catatan tambahan, saya menyarankan Anda untuk mencoba menghindari penggunaan keduanya showdan hiddenkelas, sehingga kodenya bisa lebih sederhana. Kemungkinan besar Anda tidak perlu mengatur kelas untuk sesuatu yang akan ditampilkan secara default.


11
Bisakah Anda menguraikan utilitas classNames menjadi "pendekatan yang saat ini direkomendasikan"? Apakah itu tertangkap dalam beberapa dokumen praktik terbaik yang dianggap baik di suatu tempat? Atau hanya semacam kata dari mulut di sekitar Bereaksi dan classNamessaat ini?
Alexander Nied

6
@anied Pada saat penulisan ini direkomendasikan dalam dokumentasi Bereaksi resmi: web.archive.org/web/20160602124910/http://facebook.github.io:80/…
Diego V

3
Itu masih disebutkan dalam dokumentasi terbaru : " Jika Anda sering menemukan diri Anda menulis kode seperti ini, paket classnames dapat menyederhanakannya. "
Franklin Yu

66

Jika Anda menggunakan transpiler (seperti Babel atau Traceur), Anda dapat menggunakan " string template " ES6 yang baru .

Inilah jawaban dari @ spitfire109, yang dimodifikasi sesuai:

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

Pendekatan ini memungkinkan Anda untuk melakukan hal-hal yang rapi seperti itu, memberikan salah satu s-is-shownatau s-is-hidden:

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

20
Hati-hati dengan pendekatan kedua, terutama dalam basis kode besar, karena membuat string kelas kurang dapat diterima. Misalnya, jika seseorang mencari s-is-shownatau s-is-hiddendalam basis kode, mereka tidak akan menemukan kode ini.
tandai

15

Anda dapat menggunakan String literal di sini

const Angle = ({show}) => {

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

   return <i className={angle} />
}

9

Mengeluarkan jawaban baik @ spitfire109, orang dapat melakukan sesuatu seperti ini:

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

  return names.join(' ');
}

dan kemudian dalam fungsi render:

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

membuat jsx singkat



8

Jika Anda hanya perlu satu nama kelas opsional:

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

1
Ini akan menambahkan falsekelas ketika kondisi gagal.
RA.


5

2019:

Bereaksi adalah danau banyak utilitas. Tetapi Anda tidak membutuhkan npmpaket apa pun untuk itu. buat saja suatu fungsi classnamesdan panggil ketika Anda membutuhkannya;

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

atau

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

contoh

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

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

Hanya Untuk Inspirasi

mendeklarasikan elemen pembantu dan menggunakannya togglemetode

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

contoh:

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

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

4

Solusi yang lebih elegan, yang lebih baik untuk pemeliharaan dan keterbacaan:

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

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

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

3

Anda bisa menggunakan ini:

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

2

Ini akan bekerja untuk Anda

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

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

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

1

Anda dapat menggunakan paket npm ini . Ini menangani semuanya dan memiliki opsi untuk kelas statis dan dinamis berdasarkan variabel atau fungsi.

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

Berdasarkan nilai this.props.showBulkActionsAnda dapat beralih kelas secara dinamis sebagai berikut.

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

1

Saya ingin menambahkan bahwa Anda juga dapat menggunakan konten variabel sebagai bagian dari kelas

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

Konteksnya adalah obrolan antara bot dan pengguna, dan gaya berubah tergantung dari pengirim, ini adalah hasil browser:

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

1

Ini berguna ketika Anda memiliki lebih dari satu kelas untuk ditambahkan. Anda bisa bergabung dengan semua kelas dalam array dengan spasi.

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

1

Menggantikan:

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

dengan:

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

0

Referensi ke @split fire answer, kita dapat memperbaruinya dengan templat literals, yang lebih mudah dibaca, Untuk referensi Checkout javascript templat literal

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

0

Saya menemukan ini yang menjelaskan bagaimana melakukannya dengan ternary dan dengan Classnames Library

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.