React Native - Quel est l'avantage d'utiliser StyleSheet par rapport à un objet simple?

105

Quel est exactement l'avantage d'utiliser par StyleSheet.create()rapport à un objet ordinaire?

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

Contre.

const styles = {
  container: {
    flex: 1
  }
}
corasan
la source
J'obtiens le support VSCode intellisense pour les propriétés. Voilà l'avantage.
helloworld

Réponses:

42

Citant directement à partir de la section commentaire de StyleSheet.js de React native

Qualité du code:

  • En éloignant les styles de la fonction de rendu, vous rendez le code plus facile à comprendre.

  • Nommer les styles est un bon moyen d'ajouter du sens aux composants de bas niveau dans la fonction de rendu.

Performance:

  • Créer une feuille de style à partir d'un objet de style permet de s'y référer par ID au lieu de créer un nouvel objet de style à chaque fois.

  • Il permet également d'envoyer le style une seule fois à travers le pont. Toutes les utilisations ultérieures vont faire référence à un identifiant (pas encore implémenté).

StyleSheet valide également le contenu de votre feuille de style. Ainsi, toute erreur de propriété de style incorrecte est affichée au moment de la compilation plutôt qu'au moment de l'exécution lorsque StyleSheet est réellement implémenté.

while1
la source
46
Les trois premières puces ne sont pas pertinentes pour la technique de OP consistant à déclarer l'objet de style en tant que const en dehors de la fonction de rendu.
Owen Masback le
12
Quand je lis l'explication, je ne vois toujours pas comment StyleSheet.create({styles...})c'est mieux / plus rapide que {styles...}. Le code est tout aussi propre et vous utilisez également la dénomination au lieu de l'inlining. Quelqu'un peut-il faire la lumière là-dessus?
freeall
9
StyleSheetfournit la validation à la compilation
Jeevan Takhar
10
Voté contre. Ne mettez pas d'informations non pertinentes ("en éloignant les styles de la fonction de rendu", etc.) dans votre réponse.
Roymunson
5
Évalué à la baisse, la question de l'OP était la différence entre StyleSheet.createet un objet ordinaire, pas en ligne vs un const en dehors de la classe
quirimmo
56

Il n'y a aucun avantage. Période.

Mythe 1: StyleSheetest plus performant

Il n'y a absolument aucune différence de performances entre StyleSheetet un objet déclaré en dehors de render(ce serait différent si vous créez un nouvel objet à l'intérieur à renderchaque fois). La différence de performance est un mythe.

L'origine du mythe est probablement due au fait que l'équipe React Native a essayé de le faire, mais elle n'a pas réussi. Nulle part dans la documentation officielle, vous ne trouverez quoi que ce soit sur les performances: https://facebook.github.io/react-native/docs/stylesheet.html , tandis que le code source indique "pas encore implémenté": https://github.com/ facebook / react-native / blob / master / Bibliothèques / StyleSheet / StyleSheet.js # L207

Mythe 2: StyleSheetvalide l'objet de style au moment de la compilation

Ce n'est pas vrai. Le JavaScript brut ne peut pas valider les objets au moment de la compilation.

Deux choses:

  • Il valide au moment de l'exécution, mais il en est de même lorsque vous transmettez l'objet de style à un composant. Aucune différence.
  • Il valide au moment de la compilation si vous utilisez Flow ou TypeScript , mais il en va de même une fois que vous passez l'objet comme accessoire de style à un composant, ou si vous tapez correctement l'objethint comme ci-dessous. Aucune différence non plus.
const containerStyle: ViewStyle = {
   ...
}
Nikola Mihajlović
la source
3
Vrai. Peut-être que la confusion vient de la version antérieure de leurs documents impliquant qu'ils allaient éventuellement référencer les styles par id. Cela n'est pas mentionné dans la documentation 0.59.
eremzeit le
1
THX pour démystifier. Mais la question est ouverte - Pourquoi?
Vasiliy Vanchuk
1
Plus sur p2 github.com/facebook/react-native/blob/…
Vasiliy Vanchuk
Merci pour cette réponse. Il mérite plus de votes positifs :)
ThaJay
3
Mon test indique qu'il ne validate à l' exécution sans avoir besoin de passer à un composant, par exemple StyleSheet.create( {x:{flex: "1"}} )échouera lors de l' exécution, tout comme un chèque dactylographiée sur ce au moment de la compilation.
Glenn Lawrence
24

La réponse acceptée n'est pas une réponse à la question du PO.

La question n'est pas la différence entre les styles en ligne et un en constdehors de la classe, mais pourquoi nous devrions utiliser à la StyleSheet.createplace d'un objet simple.

Après quelques recherches, ce que j'ai trouvé est le suivant (veuillez mettre à jour si vous avez des informations). Les avantages de StyleSheet.createdevraient être les suivants:

  1. Il valide les styles
  2. Meilleures performances car il crée un mappage des styles vers un ID, puis il fait référence à l'intérieur avec cet ID, au lieu de créer à chaque fois un nouvel objet. Ainsi, même le processus de mise à jour des appareils est plus rapide car vous n'envoyez pas à chaque fois tous les nouveaux objets.
quirimmo
la source
11
Ce sont des mythes. Vérifiez ma réponse.
Nikola Mihajlović
Si je définis l'objet de style en dehors de la classe (ou même en tant que propriété de classe), il sera créé une fois (ou une fois par instance). Les mêmes objets créés à nouveau ne sont pertinents qu'à l'intérieur des fonctions.
ThaJay
Ouais pour le const, mais la propriété de classe non. Propriété de classe statique oui.
quirimmo
5

Auparavant, on considérait que l'utilisation d'une feuille de style était plus performante, et était recommandée pour cette raison par l'équipe RN jusqu'à la version 0.57, mais elle n'est plus recommandée comme correctement indiqué dans une autre réponse à cette question.

La documentation RN recommande maintenant StyleSheet pour les raisons suivantes, bien que je pense que ces raisons s'appliqueraient également aux objets simples qui sont créés en dehors de la fonction de rendu:

  • En éloignant les styles de la fonction de rendu, vous rendez le code plus facile à comprendre.
  • Nommer les styles est un bon moyen d'ajouter du sens aux composants de bas niveau dans la fonction de rendu.

Alors, à mon avis, quels sont les avantages possibles de l'utilisation de StyleSheet sur des objets simples?

1) En dépit des affirmations contraires mes tests sur la RN v0.59.10 indique que vous faites obtenir une validation lors de l' appel StyleSheet.create()et tapuscrit (et probablement débit) sera également rapporter des erreurs au moment de la compilation. Même sans vérification du temps de compilation, je pense qu'il est toujours avantageux de valider les styles à l'exécution avant qu'ils ne soient utilisés pour le rendu, en particulier lorsque les composants qui utilisent ces styles peuvent être rendus conditionnellement. Cela permettra de détecter ces erreurs sans avoir à tester tous les scénarios de rendu.

2) Étant donné que StyleSheet est recommandé par l'équipe RN, ils peuvent encore espérer utiliser StyleSheet pour améliorer les performances à l'avenir, et ils peuvent également avoir d'autres améliorations possibles à l'esprit, par exemple:

3) La StyleSheet.create()validation d'exécution actuelle est utile, mais un peu limitée. Il semble être limité à la vérification de type que vous obtiendriez avec flow ou dactylographié, donc je reprendra disons flex: "1"ou borderStyle: "rubbish", mais pas width: "rubbish"car cela pourrait être une chaîne de pourcentage. Il est possible que l'équipe RN puisse améliorer cette validation à l'avenir en vérifiant des éléments tels que les chaînes de pourcentage ou les limites de plage, ou vous pouvez intégrer StyleSheet.create()votre propre fonction pour effectuer cette validation plus approfondie.

4) En utilisant StyleSheet, vous facilitez peut-être la transition vers des alternatives / extensions tierces telles que react-native-extended-stylesheet qui offrent plus.

Glenn Lawrence
la source
1

La création de vos styles via StyleSheet.createpassera par la validation uniquement lorsque la variable globale __DEV__est définie sur true (ou lors de l'exécution à l'intérieur des émulateurs Android ou IOS, voir les variables React Native DEV et PROD )

Le code source de la fonction est assez simple:

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

Je recommanderais de l'utiliser car il effectue une validation d'exécution pendant le développement, et il gèle également l'objet.

bmaggi
la source
0

Je n'ai trouvé aucune différence dans l' StyleSheetobjet between et plain, à l'exception de la validation de frappe dans TypeScript.

Par exemple, ceci (notez les différences de frappe):

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

équivaut à ceci:

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
la source