Native reagieren - Was ist der Vorteil der Verwendung von StyleSheet gegenüber einem einfachen Objekt?

104

Was genau ist der Vorteil der Verwendung StyleSheet.create()gegenüber einem einfachen Objekt?

const styles = StyleSheet.create({
  container: {
    flex: 1
  }
}

Vs.

const styles = {
  container: {
    flex: 1
  }
}
Corasan
quelle
Ich erhalte VSCode Intellisense-Unterstützung für Eigenschaften. Das ist der Vorteil.
Helloworld

Antworten:

42

Zitieren direkt aus dem Kommentarbereich von StyleSheet.js von React native

Codequalität:

  • Indem Sie Stile von der Renderfunktion entfernen, wird der Code verständlicher.

  • Das Benennen der Stile ist eine gute Möglichkeit, den Komponenten auf niedriger Ebene in der Renderfunktion eine Bedeutung zu verleihen.

Performance:

  • Wenn Sie aus einem Stilobjekt ein Stylesheet erstellen, können Sie anhand der ID darauf verweisen, anstatt jedes Mal ein neues Stilobjekt zu erstellen.

  • Es erlaubt auch, den Stil nur einmal durch die Brücke zu senden. Alle nachfolgenden Verwendungen verweisen auf eine ID (noch nicht implementiert).

Außerdem überprüft StyleSheet auch den Inhalt Ihres Stylesheets. Daher wird jeder Fehler einer falschen Stileigenschaft zum Zeitpunkt der Kompilierung und nicht zur Laufzeit angezeigt, wenn StyleSheet tatsächlich implementiert ist.

while1
quelle
46
Die ersten drei Aufzählungspunkte sind für die OP-Technik, das Stilobjekt als Konstante außerhalb der Renderfunktion zu deklarieren, irrelevant.
Owen Masback
12
Wenn ich die Erklärung lese, sehe ich immer noch nicht, wie StyleSheet.create({styles...})besser / schneller ist als {styles...}. Der Code ist genauso sauber und Sie verwenden auch Namensgebung anstelle von Inlining. Kann jemand etwas Licht ins Dunkel bringen?
freeall
9
StyleSheetbietet Validierung bei der Zusammenstellung
Jeevan Takhar
10
Abgestimmt. Fügen Sie Ihrer Antwort keine irrelevanten Informationen hinzu ("indem Sie Stile von der Renderfunktion entfernen" usw.).
Roymunson
5
Abgestimmt war die Frage des OP der Unterschied zwischen StyleSheet.createund einem einfachen Objekt, nicht inline gegen eine Konstante außerhalb der Klasse
quirimmo
55

Es gibt keinen Vorteil. Zeitraum.

Mythos 1: StyleSheetist performanter

Es gibt absolut keinen Leistungsunterschied zwischen StyleSheetund einem Objekt, das außerhalb von deklariert wurde render(es wäre anders, wenn Sie renderjedes Mal ein neues Objekt innerhalb von erstellen würden ). Der Leistungsunterschied ist ein Mythos.

Der Ursprung des Mythos liegt wahrscheinlich darin, dass das Team von React Native dies versucht hat, aber sie waren nicht erfolgreich. Nirgendwo in den offiziellen Dokumenten finden Sie Informationen zur Leistung: https://facebook.github.io/react-native/docs/stylesheet.html , während der Quellcode "noch nicht implementiert" lautet: https://github.com/ facebook / react-native / blob / master / Libraries / StyleSheet / StyleSheet.js # L207

Mythos 2: StyleSheetÜberprüft das Stilobjekt zur Kompilierungszeit

Das ist nicht wahr. Normales JavaScript kann Objekte zur Kompilierungszeit nicht validieren.

Zwei Dinge:

  • Es wird zur Laufzeit überprüft, aber auch, wenn Sie das Stilobjekt an eine Komponente übergeben. Kein Unterschied.
  • Es wird zur Kompilierungszeit überprüft , ob Sie Flow oder TypeScript verwenden , aber auch, wenn Sie das Objekt als Stil-Requisite an eine Komponente übergeben oder wenn Sie ein Objekt wie unten richtig eingeben. Auch kein Unterschied.
const containerStyle: ViewStyle = {
   ...
}
Nikola Mihajlović
quelle
3
Wahr. Vielleicht kommt die Verwirrung von der früheren Version ihrer Dokumente, die impliziert, dass sie schließlich nach ID auf Stile verweisen würden. Das wird in den 0.59-Dokumenten nicht erwähnt.
Eremzeit
1
THX zur Entmystifizierung. Aber die Frage ist offen - wofür?
Vasiliy Vanchuk
1
Plus über p2 github.com/facebook/react-native/blob/…
Vasiliy Vanchuk
Vielen Dank für diese Antwort. Es verdient mehr Upvotes :)
ThaJay
3
Mein Test zeigt an, dass es funktioniert Validate zur Laufzeit ohne Notwendigkeit an eine Komponente zu übergeben, zum Beispiel StyleSheet.create( {x:{flex: "1"}} )wird zur Laufzeit fehlschlagen, ebenso wie eine Typoskript Prüfung auf diesem zum Zeitpunkt der Kompilierung.
Glenn Lawrence
24

Die akzeptierte Antwort ist keine Antwort auf die OP-Frage.

Die Frage ist nicht der Unterschied zwischen Inline-Stilen und einem constaußerhalb der Klasse, sondern warum wir StyleSheet.createanstelle eines einfachen Objekts verwenden sollten.

Nach ein wenig Recherche habe ich Folgendes gefunden (bitte aktualisieren, wenn Sie Informationen haben). Die Vorteile von StyleSheet.createsollten folgende sein:

  1. Es validiert die Stile
  2. Bessere Leistungen, da eine Zuordnung der Stile zu einer ID erstellt wird und dann mit dieser ID nach innen verwiesen wird, anstatt jedes Mal ein neues Objekt zu erstellen. Selbst das Aktualisieren von Geräten ist schneller, da Sie nicht jedes Mal alle neuen Objekte senden.
Quirimmo
quelle
11
Das sind Mythen. Überprüfen Sie meine Antwort.
Nikola Mihajlović
Wenn ich das Stilobjekt außerhalb der Klasse (oder sogar als Klasseneigenschaft) definiere, wird es einmal (oder einmal pro Instanz) erstellt. Dieselben Objekte, die erneut erstellt werden, sind nur innerhalb von Funktionen relevant.
Donnerstag,
Ja für die Konstante, aber Klasseneigenschaft nein. Statische Klasseneigenschaft yep.
Quirimmo
5

Es verwendet , um in Betracht gezogen werden , dass ein Stylesheet mit war mehr performant und wurde empfohlen , von der RN Team aus diesem Grund bis Version 0.57, aber es ist jetzt nicht mehr zu empfehlen , da richtig in darauf hingewiesen , eine andere Antwort auf diese Frage.

In der RN-Dokumentation wird StyleSheet jetzt aus folgenden Gründen empfohlen, obwohl ich denke, dass diese Gründe auch für einfache Objekte gelten würden, die außerhalb der Renderfunktion erstellt wurden:

  • Indem Sie Stile von der Renderfunktion entfernen, wird der Code verständlicher.
  • Das Benennen der Stile ist eine gute Möglichkeit, den Komponenten auf niedriger Ebene in der Renderfunktion eine Bedeutung zu verleihen.

Was sind meiner Meinung nach die möglichen Vorteile der Verwendung von StyleSheet gegenüber einfachen Objekten?

1) Trotz gegenteiliger Behauptungen meinen Tests auf RN v0.59.10 zeigt an, dass Sie tun einige Validierung erhalten wenn Sie anrufen StyleSheet.create()und Typoskript (und wahrscheinlich fließen) wird auch Fehler bei der Kompilierung melden. Selbst ohne Überprüfung der Kompilierungszeit ist es meiner Meinung nach immer noch vorteilhaft, die Laufzeitüberprüfung von Stilen durchzuführen, bevor sie zum Rendern verwendet werden, insbesondere wenn Komponenten, die diese Stile verwenden, unter bestimmten Bedingungen gerendert werden können. Auf diese Weise können solche Fehler erkannt werden, ohne dass alle Rendering-Szenarien getestet werden müssen.

2) Da die Stylesheet wird von dem RN - Team empfohlen sie noch Hoffnung , mit Stylesheet kann die Leistung in Zukunft zu verbessern, und sie können andere mögliche Verbesserungen im Geist als auch, zum Beispiel:

3) Die aktuelle StyleSheet.create()Laufzeitvalidierung ist nützlich, aber etwas eingeschränkt. Es scheint auf die Typprüfung beschränkt zu sein, die Sie mit Flow oder Typoskript erhalten würden, also wird es sagen flex: "1"oder borderStyle: "rubbish", aber nicht, width: "rubbish"da dies eine Prozentzeichenfolge sein könnte. Es ist möglich, dass das RN-Team diese Validierung in Zukunft verbessert, indem es beispielsweise Prozentzeichenfolgen oder Bereichsbeschränkungen überprüft, oder Sie können StyleSheet.create()Ihre eigene Funktion einbinden, um diese umfassendere Validierung durchzuführen.

4) Durch die Verwendung von StyleSheet erleichtern Sie möglicherweise den Übergang zu Alternativen / Erweiterungen von Drittanbietern wie React-Native-Extended-Stylesheet , die mehr bieten.

Glenn Lawrence
quelle
1

Das Erstellen Ihrer Stile über StyleSheet.createwird nur dann überprüft, wenn die globale Variable __DEV__auf true gesetzt ist (oder wenn Sie in Android- oder IOS-Emulatoren ausgeführt werden, siehe React Native DEV- und PROD-Variablen ).

Die Funktion Source - Code ist ziemlich einfach:

create < +S: ____Styles_Internal > (obj: S): $ReadOnly < S > {
  // TODO: This should return S as the return type. But first,
  // we need to codemod all the callsites that are typing this
  // return value as a number (even though it was opaque).
  if (__DEV__) {
    for (const key in obj) {
      StyleSheetValidation.validateStyle(key, obj);
      if (obj[key]) {
        Object.freeze(obj[key]);
      }
    }
  }
  return obj;
}

Ich würde empfehlen, es zu verwenden, da es während der Entwicklung eine Laufzeitüberprüfung durchführt und das Objekt einfriert.

bmaggi
quelle
0

Ich habe keine Unterschiede zwischen dem StyleSheeteinfachen und dem einfachen Objekt gefunden, außer bei der Typüberprüfung in TypeScript.

Zum Beispiel dies (beachten Sie die Tippunterschiede):

import { View, Text, Image, StyleSheet } from 'react-native';
import logo from './logo.svg';

export default class App extends Component {
  render() {
    return (
      <View style={styles.someViewStyle}>
        <Text style={styles.someTextStyle}>Text Here</Text>
        <Image style={styles.someImageStyle} source={logo} />
      </View>
    );
  }
}

const styles: StyleSheet.create({
  someViewStyle: {
    backgroundColor: '#FFF',
    padding: 10,
  },
  someTextStyle: {
    fontSize: 24,
    fontWeight: '600',
  },
  someImageStyle: {
    height: 50,
    width: 100,
  },
});

gleich dem:

import { View, Text, Image, ViewStyle, TextStyle, ImageStyle } from 'react-native';
import logo from './logo.svg';

export default class App extends Component {
  render() {
    return (
      <View style={styles.someViewStyle}>
        <Text style={styles.someTextStyle}>Text Here</Text>
        <Image style={styles.someImageStyle} source={logo} />
      </View>
    );
  }
}

const styles: {
  someViewStyle: ViewStyle;
  someTextStyle: TextStyle;
  someImageStyle: ImageStyle;
} = {
  someViewStyle: {
    backgroundColor: '#FFF',
    padding: 10,
  },
  someTextStyle: {
    fontSize: 24,
    fontWeight: '600',
  },
  someImageStyle: {
    height: 50,
    width: 100,
  },
};
Slavik Meltser
quelle