React'te koşullu stil oluşturmanın doğru yolu


93

Şu anda biraz React yapıyorum ve koşullu şekillendirme yapmanın "doğru" bir yolu olup olmadığını merak ediyordum. Öğreticide kullandıkları

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

Satır içi stil kullanmamayı tercih ederim, bu nedenle koşullu stili kontrol etmek için bir sınıf kullanmak istiyorum. React düşüncesinde buna nasıl yaklaşılır? Yoksa bu satır içi şekillendirme yöntemini mi kullanmalıyım?


1
Sanırım yapmış reduxve reactkafan karışmış olabilir . Redux'un stil ile ilgisi yok.
rossipedia

3
Sanırım tercihiniz belgeler için yerinde, ancak biçimlendirme değişim uyumluluğunun önemli olmadığı uygulamalar için aşırı hevesli. Bazı büyük web uygulamaları aslında sınıflardan kurtuluyor ve yalnızca satır içi stili kullanıyor, bu da uygulanan 5 kuraldan hangisinin metni kalınlaştırdığına göre daha tahmin edilebilir ve daha kolay anlaşılabilir. öznitelikler dinamik olduğunda, tekrarlayan belgelerde yaptığınız gibi çok fazla bant genişliği tasarrufu sağlamazsınız. Uygulamanın semantik (kaynağı görüntüle biçimlendirme) önemli ya ... o değil
dandavis

@rossipedia ah evet teşekkür ederim, karıştım, bunu düşünürken redux eğitimine bakıyordum, teşekkür ederim!
davidhtien

Basamaklama nedeniyle metin dekorasyonunun değerinin ne olacağından emin değilseniz ve yalnızca tamamlama doğruysa bir çizgi geçişi uygulamak istiyorsanız, bir stil nesnesi oluşturmanız gerekir. Bu şekilde, başka bir değer olduğunda yanlışlıkla hiçbiri olarak ayarlamazsınız. const style = {} if (complete) {style ['textDecoration'] = 'line-through'}
Edward

Yanıtlar:


78

Bir sınıf adı kullanmayı tercih ediyorsanız, kesinlikle bir sınıf adı kullanın.

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

Sınıf adları paketini de yararlı bulabilirsiniz . Bununla kodunuz şöyle görünecektir:

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

Koşullu stil yapmanın "doğru" bir yolu yoktur. Sizin için en iyi olanı yapın. Kendim için, satır içi stilden kaçınmayı ve sınıfları az önce anlatılan şekilde kullanmayı tercih ederim.

POSTSCRIPT [06-AUG-2019]

React'in stil oluşturma konusunda yeterince fikir sahibi olmadığı doğru olsa da, bugünlerde CSS-in-JS çözümü öneriyorum; yani stilize edilmiş bileşenler veya duygu . React'te yeniyseniz, başlamak için CSS sınıflarına veya satır içi stillere bağlı kalın. Ancak React konusunda rahat olduğunuzda, bu kütüphanelerden birini benimsemenizi tavsiye ederim. Bunları her projede kullanıyorum.


Merhaba, koşullu şekillendirme yönteminiz olarak className kullanmaya karar verdiyseniz. Olmadan classNames lib. Bunun undefinedyerine kullanmanızı tavsiye ederim null. className⚡️ - | tipini (tanımsız Dize) - tesiste Dize veya tanımsız yazın girdi olarak alır
0xx

3
@JadRizk daha da iyi bir yaklaşım, eğer onu ayarlamak için geçerli bir değere sahip değilseniz, className'i hiç ayarlamamaktır. const attrs = completed?{className:'text-strike'}:{}sonra <li {...attrs}>text to maybe strike</li>(yayılma operatörü). Bu şekilde, atayacak iyi bir değeriniz olmadıkça className'i hiç ayarlamazsınız. Bu, mevcut değerin ne olduğunu bilemeyeceğiniz bazı satır içi stilleri ayarlamak için önemli bir yaklaşımdır (çünkü kontrol edemeyebileceğiniz bir dosyada CSS tarafından ayarlanabilir).
LinuxDisciple

@LinuxDisciple, tüm alanlar falsey olarak değerlendirilirse classnamesboş bir dize döndürür. Bu, herhangi bir CSS'den etkilenmeyecektir.
David

@ DavidL.Walsh 21 saat önce JadRizk'in çözümünün yanlış bir seçim olduğunu nullve undefinedbunun html'de class(yani <p class></p>yerine <p></p>) bir değer olmayan özniteliğe neden olacağını düşündüm, bu yüzden ayarlamadan kaçınan bir yöntem sağladım className. Olduğu gibi, JadRizk'in çözümü hakkında yanılmışım. Belirtilen sorun için, JadRizk'in iyileştirmesi ile çözümünüzün en iyisi olduğuna inanıyorum. Sözdizimim rastgele bir sahne ve değerleri listesi oluşturabilir, ancak bu sadece bir sınıf adı belirlemek için fazla bir şeydir.
LinuxDisciple

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

Yukarıdaki kodu kontrol edin. Bu hile yapacak.


3
Tam olarak böyle bir şey arıyordum. Koşullu satır içi stil, teşekkür ederim.
Souvik Ghosh

<div style = {{visibility: this.state.driverDetails.firstName! == undefined? 'visible': 'hidden'}}> </div>. == içinde küçük yazım hatası.
vinayak shahdeo

31

Satır içi stilleri koşullu olarak uygulamanız gerekiyorsa (tümünü veya hiçbir şeyi uygulayın), bu gösterim de çalışır:

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

'Bazı Koşulların' yerine getirilmemesi durumunda boş nesneyi iletirsiniz.


2
Yine de bu kalıp gereksiz bir fark yaratmıyor mu? DOM diffing benim anlayış olduğunu styleburada pervane hep JavaScript beri değiştirecek {} != {} Ben diffing hakkında doğru isem "belki de kullanıma daha iyidir, undefined" yerine " {}"
Dawson B

1
İyi not. Bunun hakkında emin değilim.
Vlado

8

İlk olarak, bir stil meselesi olarak size katılıyorum - ayrıca satır içi stiller yerine sınıfları koşullu olarak uygularım (ve ayrıca yaparım). Ama aynı tekniği kullanabilirsiniz:

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

Daha karmaşık durum kümeleri için, bir sınıf dizisi biriktirin ve bunları uygulayın:

var classes = [];

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

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

6

bunun yerine:

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

kısa devre yaparak aşağıdakileri deneyebilirsiniz:

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

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

bağlantıdaki önemli bilgiler:

Kısa devre, JavaScript'te bir AND ifadesini (&&) değerlendirirken, ilk işlenen yanlışsa JavaScript'in kısa devre yapacağı ve hatta ikinci işlenene bakmayacağı anlamına gelir.

İlk işlenen yanlışsa bunun yanlış döneceğini belirtmekte fayda var, bu yüzden bunun tarzınızı nasıl etkileyeceğini düşünmeniz gerekebilir.

Diğer çözümler daha iyi uygulama olabilir, ancak paylaşmaya değer olacağını düşündük.


3

Satır içi stili ve yayılma operatörünü kullanmanın başka bir yolu

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

Bu şekilde, koşula bağlı olarak aynı anda bir grup özellik eklemek istediğiniz bazı durumlarda faydalı olabilir.


1
Varsayılan bir stili değiştirmek istemiyorsanız iyi bir yaklaşım
dhilt

2

Aynı soruyu cevaplamaya çalışırken bu soru ile karşılaştım. McCrohan'ın sınıf dizisi ve birleştirme yaklaşımı sağlam.

Deneyimlerime dayanarak, React'e dönüştürülen birçok eski Ruby koduyla çalışıyorum ve bileşenleri oluştururken kendimi hem mevcut css sınıflarına hem de satır içi stillere ulaşırken buluyorum.

bir bileşenin içindeki örnek pasaj:

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

Yine, kendimi eski css koduna ulaşırken buluyorum, onu bileşenle "paketliyor" ve devam ediyorum.

Bu yüzden, gerçekten "en iyi" olanın biraz havada olduğunu hissediyorum, çünkü bu etiket projenize bağlı olarak büyük ölçüde değişecektir.



0

Stilleri işlemenin en iyi yolu, bir dizi css özelliklerine sahip sınıfları kullanmaktır.

misal:

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

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

0

Bunun gibi bir şey kullanabilirsin.

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

Ya da, dinamik ve koşullu className props'larıyla çalışmayı daha basit hale getirmek için (özellikle koşullu dize işleminden daha fazla) sınıf adları NPM paketini kullanabilirsiniz .

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'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.