Richtige Vorgehensweise beim bedingten Styling in React


91

Ich mache gerade eine Reaktion und habe mich gefragt, ob es einen "richtigen" Weg gibt, bedingtes Styling zu machen. Im Tutorial verwenden sie

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

Ich bevorzuge es, kein Inline-Styling zu verwenden, daher möchte ich stattdessen eine Klasse verwenden, um das bedingte Styling zu steuern. Wie würde man dies in der React-Denkweise angehen? Oder sollte ich einfach dieses Inline-Styling verwenden?


1
Ich denke, Sie könnten reduxund reactverwirrt haben. Redux hat nichts mit Styling zu tun.
Wikipedia

3
Ich denke, Ihre Präferenz ist genau richtig für Dokumente, aber übermäßig eifrig für Anwendungen, bei denen die Kompatibilität mit Markup-Austausch nicht wichtig ist. Einige wichtige Web-Apps entfernen tatsächlich Klassen und verwenden nur den Inline-Stil, der vorhersehbarer und leichter zu überlegen ist, als welche der 5 angewendeten Regeln den Text fett macht. Wenn die Attribute dynamisch sind, sparen Sie nicht viel Bandbreite wie bei sich wiederholenden Dokumenten. Die Semantik der App (View-Source-Markup) ist auch nicht so wichtig ...
Dandavis

@rossipedia ah ja danke, war durcheinander, habe mir das Redux-Tutorial angesehen, als ich darüber nachgedacht habe, danke!
Davidhtien

Wenn Sie sich aufgrund der Kaskade nicht sicher sind, welchen Wert die Textdekoration haben wird, und Sie nur dann einen Line-Through anwenden möchten, wenn der Vorgang vollständig ist, müssen Sie ein Stilobjekt erstellen. Auf diese Weise setzen Sie es nicht versehentlich auf none, wenn es sich um einen anderen Wert handelt. const style = {} if (complete) {style ['textDecoration'] = 'line-through'}
Edward

Antworten:


77

Wenn Sie lieber einen Klassennamen verwenden möchten, verwenden Sie auf jeden Fall einen Klassennamen.

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

Möglicherweise finden Sie auch das Paket mit den Klassennamen hilfreich. Damit würde Ihr Code folgendermaßen aussehen:

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

Es gibt keine "richtige" Möglichkeit, bedingtes Styling durchzuführen. Tun Sie, was für Sie am besten funktioniert. Für mich selbst vermeide ich lieber Inline-Styling und verwende Klassen auf die gerade beschriebene Weise.

POSTSCRIPT [06-AUG-2019]

Obwohl React in Bezug auf das Styling nicht begeistert ist, würde ich heutzutage eine CSS-in-JS-Lösung empfehlen. nämlich gestaltete Komponenten oder Emotionen . Wenn Sie React noch nicht kennen, halten Sie sich zunächst an CSS-Klassen oder Inline-Stile. Sobald Sie mit React vertraut sind, empfehle ich, eine dieser Bibliotheken zu übernehmen. Ich benutze sie in jedem Projekt.


Hallo, wenn Sie sich entschieden haben, className als bedingte Styling-Methode zu verwenden. Ohne die classNames lib. Ich rate Ihnen, undefinedanstelle von zu verwenden null. Die classNameEigenschaft nimmt als Eingabetyp einen String oder einen undefinierten Typ (String | undefined) - ⚡️
0xx

3
@JadRizk Noch besser ist es, className überhaupt nicht festzulegen, wenn Sie keinen gültigen Wert zum Festlegen haben. const attrs = completed?{className:'text-strike'}:{}dann <li {...attrs}>text to maybe strike</li>(Spread Operator). Auf diese Weise setzen Sie className überhaupt nicht, es sei denn, Sie haben einen guten Wert zuzuweisen. Dies ist ein wichtiger Ansatz zum Festlegen einiger Inline-Stile, bei denen Sie den aktuellen Wert nicht kennen (da er möglicherweise von CSS in einer Datei festgelegt wird, die Sie möglicherweise nicht steuern).
LinuxDisciple

@LinuxDisciple Wenn alle Felder zu Falsey ausgewertet werden, wird classnamesnur eine leere Zeichenfolge zurückgegeben. Dies wird von keinem CSS beeinflusst.
David L. Walsh

@ DavidL.Walsh Vor 21 Stunden dachte ich, JadRizks Lösung sei eine falsche Wahl zwischen nullund undefineddas würde immer noch zu einem classAttribut ohne Wert im HTML führen (dh <p class></p>anstelle von <p></p>), also habe ich eine Methode bereitgestellt, die das Festlegen classNameüberhaupt vermeidet . Zufällig habe ich mich bei der Lösung von JadRizk geirrt. Für das angegebene Problem halte ich Ihre Lösung mit JadRizks Verfeinerung für die beste. Meine Syntax kann eine beliebige Liste von Requisiten und deren Werten bedingt festlegen, aber es ist übertrieben, nur einen Klassennamen festzulegen.
LinuxDisciple

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

Überprüfen Sie den obigen Code. Das wird den Trick machen.


3
War genau auf der Suche nach so etwas. Bedingtes Inline-Styling, danke.
Souvik Ghosh

<div style = {{sichtbarkeit: this.state.driverDetails.firstName! == undefined? 'sichtbar': 'versteckt'}}> </ div>. Kleiner Tippfehler in ==.
Vinayak Shahdeo

29

Wenn Sie Inline-Stile bedingt anwenden müssen (alles oder nichts anwenden), funktioniert diese Notation auch:

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

Falls 'someCondition' nicht erfüllt ist, übergeben Sie ein leeres Objekt.


2
Erzeugt dieses Muster nicht einen unnötigen Unterschied? Mein Verständnis von DOM-Unterschied ist, dass sich die styleRequisite hier immer ändern würde, da in Javascript. {} != {} Wenn ich in Bezug auf den Unterschied richtig bin, ist es vielleicht besser, " undefined" anstelle von " {}" zu verwenden
Dawson B

1
Gute Notiz. Da bin ich mir nicht sicher.
Vlado

8

Erstens stimme ich Ihnen stilistisch zu - ich würde auch (und auch) bedingt Klassen anstelle von Inline-Stilen anwenden. Sie können jedoch dieselbe Technik verwenden:

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

Sammeln Sie für komplexere Statussätze ein Array von Klassen und wenden Sie sie an:

var classes = [];

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

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

6

an Stelle von:

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

Sie können Folgendes mit Kurzschluss versuchen:

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

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

Schlüsselinformation aus dem Link:

Kurzschluss bedeutet, dass in JavaScript bei der Auswertung eines UND-Ausdrucks (&&), wenn der erste Operand falsch ist, JavaScript kurzschließt und nicht einmal den zweiten Operanden betrachtet.

Es ist erwähnenswert, dass dies false zurückgeben würde, wenn der erste Operand false ist. Daher müssen Sie möglicherweise berücksichtigen, wie sich dies auf Ihren Stil auswirkt.

Die anderen Lösungen sind möglicherweise mehr bewährte Methoden, aber es lohnt sich, sie zu teilen.


2

Ich bin auf diese Frage gestoßen, als ich versucht habe, dieselbe Frage zu beantworten. McCrohans Ansatz mit dem Klassenarray & Join ist solide.

Durch meine Erfahrung habe ich mit viel altem Ruby-Code gearbeitet, der in React konvertiert wird, und während wir die Komponente (n) aufbauen, greife ich sowohl nach vorhandenen CSS-Klassen als auch nach Inline-Stilen.

Beispiel-Snippet innerhalb einer Komponente:

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

Wieder greife ich nach altem CSS-Code, "verpacke" ihn mit der Komponente und gehe weiter.

Ich habe wirklich das Gefühl, dass es ein bisschen in der Luft liegt, was "am besten" ist, da dieses Label je nach Projekt sehr unterschiedlich sein wird.


Sie sollten classNames nicht mit style attribute kombinieren, das ist ein bisschen
chaotisch

1

Eine andere Möglichkeit, den Inline-Stil und den Spread-Operator zu verwenden

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

Diese Methode ist in einigen Situationen hilfreich, in denen Sie eine Reihe von Eigenschaften gleichzeitig hinzufügen möchten, basierend auf der Bedingung.


0

Der beste Weg, um mit dem Styling umzugehen, ist die Verwendung von Klassen mit einer Reihe von CSS-Eigenschaften.

Beispiel:

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

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

0

Sie können so etwas verwenden.

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

Sie können auch das NPM-Paket classnames verwenden, um die Arbeit mit dynamischen und bedingten className-Requisiten zu vereinfachen (insbesondere mehr als die Manipulation bedingter Zeichenfolgen).

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'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.