Cara yang benar untuk menangani gaya bersyarat di React


94

Saya sedang melakukan React sekarang dan saya bertanya-tanya apakah ada cara yang "benar" untuk melakukan gaya bersyarat. Dalam tutorial yang mereka gunakan

style={{
  textDecoration: completed ? 'line-through' : 'none'
}}

Saya lebih suka tidak menggunakan gaya sebaris jadi saya ingin menggunakan kelas untuk mengontrol gaya bersyarat. Bagaimana seseorang mendekati ini dengan cara berpikir React? Atau haruskah saya menggunakan cara gaya sebaris ini?


1
Saya pikir Anda mungkin pernah reduxdan reactbingung. Redux tidak ada hubungannya dengan gaya.
rossipedia

3
Saya pikir preferensi Anda tepat untuk dokumen, tetapi terlalu bersemangat untuk aplikasi di mana markup interchange compat tidak penting. beberapa aplikasi web utama benar-benar menyingkirkan kelas dan hanya menggunakan gaya sebaris, yang lebih dapat diprediksi dan lebih mudah untuk dipikirkan daripada 5 aturan yang diterapkan yang membuat teks menjadi tebal. ketika atributnya dinamis, Anda tidak menghemat banyak bandwidth seperti yang Anda lakukan dengan dokumen berulang. semantik aplikasi (markup lihat-sumber) juga tidak terlalu penting ...
dandavis

@rossipedia ah ya terima kasih, ada campur aduk, sedang melihat tutorial redux ketika memikirkan hal ini, terima kasih!
davidhtien

Jika Anda tidak yakin berapa nilai dekorasi teks karena kaskade dan Anda hanya ingin menerapkan garis-tayang jika tuntas benar, Anda harus membangun objek gaya. Dengan cara ini, Anda tidak menyetelnya ke none secara tidak sengaja ketika nilainya lain. const style = {} if (complete) {style ['textDecoration'] = 'line-through'}
Edward

Jawaban:


78

Jika Anda lebih suka menggunakan nama kelas, tentu saja gunakan nama kelas.

className={completed ? 'text-strike' : null}

Anda juga dapat menemukan classnames paket membantu. Dengannya, kode Anda akan terlihat seperti ini:

className={classNames({ 'text-strike': completed })}

Tidak ada cara yang "benar" untuk melakukan gaya bersyarat. Lakukan apa pun yang terbaik untuk Anda. Untuk diri saya sendiri, saya lebih suka menghindari gaya sebaris dan menggunakan kelas dengan cara yang baru saja dijelaskan.

POSTSCRIPT [06-AGUSTUS-2019]

Meskipun tetap benar bahwa React tidak berpandangan sama tentang styling, hari ini saya akan merekomendasikan solusi CSS-in-JS; yaitu komponen gaya atau emosi . Jika Anda baru mengenal React, gunakan kelas CSS atau gaya sebaris untuk memulai. Tetapi setelah Anda merasa nyaman dengan React, saya sarankan untuk mengadopsi salah satu perpustakaan ini. Saya menggunakannya di setiap proyek.


Halo, jika Anda memutuskan untuk menggunakan className sebagai metode gaya bersyarat Anda. Tanpa classNames lib. Saya menyarankan Anda untuk menggunakan undefinedbukan null. The classNameproperti mengambil sebagai masukan ketik String atau terdefinisi - jenis (String | terdefinisi) - ⚡️
0xx

3
Pendekatan @JadRizk yang lebih baik adalah tidak menyetel className sama sekali jika Anda tidak memiliki nilai yang valid untuk disetel. const attrs = completed?{className:'text-strike'}:{}lalu <li {...attrs}>text to maybe strike</li>(operator sebar). Dengan cara itu Anda tidak menyetel className sama sekali kecuali Anda memiliki nilai yang bagus untuk ditetapkan. Ini adalah pendekatan penting untuk menyetel beberapa gaya sebaris di mana Anda tidak dapat mengetahui apa nilainya saat ini (karena dapat disetel oleh CSS dalam file yang mungkin tidak Anda kontrol).
LinuxDisciple

@LinuxDisciple jika semua bidang bernilai falsey maka classnameshanya mengembalikan string kosong. Ini tidak akan terpengaruh oleh CSS apa pun.
David L. Walsh

@ DavidL.Walsh 21 jam yang lalu saya pikir solusi JadRizk adalah pilihan yang salah antara nulldan undefineditu masih akan menghasilkan classatribut tanpa nilai di html ( <p class></p>bukan <p></p>) jadi saya menyediakan metode yang menghindari pengaturan classNamesama sekali. Kebetulan saya salah tentang solusi JadRizk. Untuk masalah yang disebutkan, saya yakin solusi Anda dengan penyempurnaan JadRizk adalah yang terbaik. Sintaks saya dapat mengatur daftar sembarang alat peraga dan nilainya secara bersyarat, tetapi itu berlebihan hanya untuk menetapkan nama kelas.
LinuxDisciple

106
 <div style={{ visibility: this.state.driverDetails.firstName != undefined? 'visible': 'hidden'}}></div>

Lihat kode di atas. Itu akan berhasil.


3
Persis mencari sesuatu seperti ini. Gaya sebaris bersyarat, terima kasih.
Souvik Ghosh

<div style = {{visibility: this.state.driverDetails.firstName! == undefined? 'terlihat': 'tersembunyi'}}> </div>. Salah ketik kecil di ==.
vinayak shahdeo

31

Jika Anda perlu menerapkan gaya sebaris secara bersyarat (menerapkan semua atau tidak sama sekali), notasi ini juga berfungsi:

style={ someCondition ? { textAlign:'center', paddingTop: '50%'} : {}}

Jika 'someCondition' tidak terpenuhi maka Anda meneruskan objek kosong.


2
Bukankah pola ini menciptakan perbedaan yang tidak perlu? Pemahaman saya tentang perbedaan DOM adalah bahwa stylepenyangga di sini akan selalu berubah karena dalam Javascript {} != {} Jika saya benar tentang perbedaan, mungkin lebih baik menggunakan " undefined" daripada " {}"
Dawson B

1
Catatan bagus. Saya tidak yakin tentang ini.
Vlado

8

Pertama, saya setuju dengan Anda sebagai masalah gaya - saya juga akan (dan juga) menerapkan kelas secara kondisional daripada gaya sebaris. Tapi Anda bisa menggunakan teknik yang sama:

<div className={{completed ? "completed" : ""}}></div>

Untuk kumpulan status yang lebih kompleks, kumpulkan array kelas dan terapkan:

var classes = [];

if (completed) classes.push("completed");
if (foo) classes.push("foo");
if (someComplicatedCondition) classes.push("bar");

return <div className={{classes.join(" ")}}></div>;

6

alih-alih ini:

style={{
  textDecoration: completed ? 'line-through' : 'none'
}}

Anda dapat mencoba yang berikut ini menggunakan korsleting:

style={{
  textDecoration: completed && 'line-through'
}}

https://codeburst.io/javascript-short-circuit-conditionals-bbc13ac3e9eb

bit informasi kunci dari tautan:

Hubung singkat berarti bahwa dalam JavaScript saat kita mengevaluasi ekspresi AND (&&), jika operan pertama salah, JavaScript akan mengalami korsleting dan bahkan tidak melihat operan kedua.

Perlu dicatat bahwa ini akan mengembalikan false jika operan pertama salah, jadi mungkin harus mempertimbangkan bagaimana hal ini akan memengaruhi gaya Anda.

Solusi lain mungkin lebih merupakan praktik terbaik, tetapi menurut saya akan bermanfaat untuk dibagikan.


3

Cara lain, menggunakan gaya sebaris dan operator sebaran

style={{
  ...completed ? { textDecoration: completed } : {}
}}

Cara tersebut berguna dalam beberapa situasi di mana Anda ingin menambahkan sekumpulan properti pada saat yang sama berdasarkan kondisi.


1
Pendekatan yang bagus jika Anda tidak ingin mengubah gaya default
lakukan

2

Saya menemukan pertanyaan ini ketika mencoba menjawab pertanyaan yang sama. Pendekatan McCrohan dengan class array & join solid.

Melalui pengalaman saya, saya telah bekerja dengan banyak kode ruby ​​lawas yang diubah menjadi React dan saat kami membangun komponen, saya mendapati diri saya menjangkau kelas css dan gaya sebaris yang ada.

cuplikan contoh di dalam sebuah komponen:

// if failed, progress bar is red, otherwise green 
<div
    className={`progress-bar ${failed ? failed' : ''}`}
    style={{ width: this.getPercentage() }} 
/>

Sekali lagi, saya menemukan diri saya menjangkau kode css lama, "mengemasnya" dengan komponen dan melanjutkan.

Jadi, saya benar-benar merasa agak tidak tahu apa yang "terbaik" karena label itu akan sangat bervariasi tergantung pada proyek Anda.


Anda tidak boleh menggabungkan classNames dengan atribut style, itu agak berantakan
Sebastian Voráč

0

Cara terbaik untuk menangani penggayaan adalah dengan menggunakan kelas dengan set properti css.

contoh:

<Component className={this.getColor()} />

getColor() {
    let class = "badge m2";
    class += this.state.count===0 ? "warning" : danger;
    return class;
}

0

Anda bisa menggunakan sesuatu seperti ini.

render () {
    var btnClass = 'btn';
    if (this.state.isPressed) btnClass += ' btn-pressed';
    else if (this.state.isHovered) btnClass += ' btn-over';
    return <button className={btnClass}>{this.props.label}</button>;
  }

Atau yang lain, Anda dapat menggunakan classnames paket NPM untuk membuat dinamis dan className bersyarat alat peraga sederhana untuk bekerja dengan (terutama lebih daripada manipulasi string bersyarat).

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
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.