Reactで条件付きスタイリングを処理する正しい方法


101

私は今Reactを行っていますが、条件付きスタイリングを行う「正しい」方法があるかどうか疑問に思っていました。彼らが使用するチュートリアルでは

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

インラインスタイルを使用したくないので、代わりにクラスを使用して条件付きスタイルを制御したいと思います。Reactの考え方でこれにどのようにアプローチしますか?それとも、このインラインスタイリング方法を使用する必要がありますか?


1
私はあなたが持っていreduxreact混乱しているかもしれないと思います。Reduxはスタイリングとは何の関係もありません。
rossipedia 2016

3
あなたの好みはドキュメントにぴったりだと思いますが、マークアップ交換互換性が重要ではないアプリケーションには熱心すぎます。一部の主要なWebアプリは、実際にはクラスを削除し、インラインスタイルのみを使用しています。これは、適用される5つのルールのどれがテキストを太字にするよりも予測可能で推論が容易です。属性が動的である場合、繰り返しのドキュメントの場合のように帯域幅をあまり節約できません。アプリケーションのセマンティクス(ビューソースのマークアップ)が重要なのはどちらか...ということではありません
dandavis

@rossipediaああ、ありがとう、混乱して、これについて考えるときにreduxチュートリアルを見ていました、ありがとう!
davidhtien 2016年

カスケードが原因でtext-decorationの値がわからず、completeがtrueの場合にのみラインスルーを適用する場合は、スタイルオブジェクトを作成する必要があります。このようにして、別の値であったときに誤ってnoneに設定することはありません。const style = {} if(complete){style ['textDecoration'] = 'line-through'}
Edward

回答:


80

クラス名を使用したい場合は、必ずクラス名を使用してください。

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

classnamesパッケージも役立つ場合があります。これを使用すると、コードは次のようになります。

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

条件付きスタイリングを行う「正しい」方法はありません。自分に最適なことは何でもしてください。私自身は、インラインスタイルを避け、今説明した方法でクラスを使用することを好みます。

POSTSCRIPT [2019年8月6日]

Reactがスタイリングについて無関心であることは事実ですが、最近はCSS-in-JSソリューションをお勧めします。つまり、スタイル設定されたコンポーネントまたは感情。Reactを初めて使用する場合は、最初にCSSクラスまたはインラインスタイルに固執してください。しかし、Reactに慣れたら、これらのライブラリの1つを採用することをお勧めします。私はすべてのプロジェクトでそれらを使用しています。


条件付きスタイリングメソッドとしてclassNameを使用することにした場合は、ねえ。なしclassNames lib。のundefined代わりに使用することをお勧めしますnullclassName⚡️ - |タイプ(未定義の文字列) -プロパティは、文字列を入力するか、未定義の入力として受け取り
0XX

4
@JadRizkのさらに優れたアプローチは、classNameに設定する有効な値がない場合は、classNameをまったく設定しないことです。const attrs = completed?{className:'text-strike'}:{}次に<li {...attrs}>text to maybe strike</li>(スプレッド演算子)。そうすれば、割り当てる適切な値がない限り、classNameをまったく設定しません。これは、現在の値がわからないインラインスタイルを設定するための重要なアプローチです(制御できないファイルのCSSによって設定される可能性があるため)。
LinuxDisciple

@LinuxDiscipleすべてのフィールドがfalseと評価された場合classnamesは、空の文字列を返します。これはCSSの影響を受けません。
David

@ DavidL.Walsh 21時間前、JadRizkのソリューションは誤った選択でnullありundefined、それでもclasshtmlに値のない属性(つまりでは<p class></p>なく<p></p>)が生じると思ったので、設定classNameをまったく回避するメソッドを提供しました。たまたま、私はJadRizkのソリューションについて間違っていました。述べられた問題については、JadRizkの改良によるあなたの解決策が最善であると私は信じています。私の構文では、小道具とその値の任意のリストを条件付きで設定できますが、クラス名を設定するだけではやり過ぎです。
LinuxDisciple

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

上記のコードを確認してください。それでうまくいきます。


4
まさにこのようなものを探していました。条件付きインラインスタイリング、ありがとうございます。
SouvikGhosh18年

<div style = {{visibility:this.state.driverDetails.firstName!== undefined?'visible': 'hidden'}}> </ div>。==の小さなタイプミス。
vinayakshahdeo20年1

37

インラインスタイルを条件付きで適用する(すべてまたはまったく適用しない)必要がある場合は、この表記も機能します。

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

'someCondition'が満たされない場合は、空のオブジェクトを渡します。


2
しかし、このパターンは不要な差分を作成しませんか?DOMは、差分の私の理解では、ということですstyleここ小道具は常にJavaScriptで以来、変化するであろう{} != {} 、私は差分の程度正しいんだ場合は、「多分それは使用することをお勧めします、undefined」の代わりに「{}
ドーソンB

1
良いメモ。これについてはよくわかりません。
ヴラド

8

まず、スタイルの問題としてあなたに同意します。インラインスタイルではなく、条件付きでクラスを適用します(また、そうします)。ただし、同じ手法を使用できます。

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

より複雑な状態のセットの場合は、クラスの配列を蓄積して適用します。

var classes = [];

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

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

8

これの代わりに:

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

短絡を使用して次のことを試すことができます。

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

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

リンクからの情報の重要なビット:

短絡とは、JavaScriptでAND式(&&)を評価するときに、最初のオペランドがfalseの場合、JavaScriptが短絡し、2番目のオペランドを見ることさえないことを意味します。

最初のオペランドがfalseの場合、これはfalseを返すため、これがスタイルにどのように影響するかを考慮する必要がある場合があることに注意してください。

他の解決策はよりベストプラクティスかもしれませんが、共有する価値があると考えました。


4

別の方法として、インラインスタイルとスプレッド演算子を使用します

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

この方法は、条件に基づいて同時に多数のプロパティを追加する場合に役立ちます。


1
デフォルトのスタイルを変更したくない場合の
優れたアプローチ

2

同じ質問に答えようとしているときに、この質問に出くわしました。クラス配列と結合を使用したMcCrohanのアプローチは堅実です。

私の経験を通して、私はReactに変換されている多くのレガシーRubyコードを扱ってきました。コンポーネントを構築するにつれて、既存のcssクラスとインラインスタイルの両方に手を差し伸べていることに気付きます。

コンポーネント内のスニペットの例:

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

繰り返しになりますが、レガシーcssコードに手を伸ばし、コンポーネントと一緒に「パッケージ化」して次に進みます。

ですから、プロジェクトによってラベルが大きく異なるので、何が「ベスト」なのかは少し気になります。


あなたは混乱のビットのこと、スタイル属性でクラス名を組み合わせてはいけません
セバスチャンVoráč

0

スタイリングを処理する最良の方法は、cssプロパティのセットを持つクラスを使用することです。

例:

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

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

0

あなたはこのような何かを使うことができます。

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

または、classnames NPMパッケージを使用して、動的で条件付きのclassName小道具を簡単に操作できるようにすることができます(特に条件付き文字列操作よりも簡単です)。

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'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.