React Native - Qual è il vantaggio dell'utilizzo di StyleSheet rispetto a un oggetto semplice?


105

Qual è esattamente il vantaggio dell'utilizzo StyleSheet.create()rispetto a un oggetto semplice?

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

Vs.

const styles = {
  container: {
    flex: 1
  }
}

Ottengo il supporto VSCode intellisense per le proprietà. Questo è il vantaggio.
helloworld

Risposte:


42

Citando direttamente dalla sezione commenti di StyleSheet.js di React native

Qualità del codice:

  • Allontanando gli stili dalla funzione di rendering, si semplifica la comprensione del codice.

  • Assegnare un nome agli stili è un buon modo per aggiungere significato ai componenti di basso livello nella funzione di rendering.

Prestazione:

  • Creare un foglio di stile da un oggetto di stile rende possibile fare riferimento ad esso tramite ID invece di creare ogni volta un nuovo oggetto di stile.

  • Consente inoltre di inviare lo stile una sola volta attraverso il bridge. Tutti gli usi successivi faranno riferimento a un ID (non ancora implementato).

Anche StyleSheet convalida anche il contenuto del tuo foglio di stile. Pertanto, qualsiasi errore di proprietà di stile errata viene visualizzato al momento della compilazione anziché in fase di esecuzione quando StyleSheet è effettivamente implementato.


46
I primi tre punti elenco sono irrilevanti per la tecnica di OP di dichiarare l'oggetto di stile come una const al di fuori della funzione di rendering.
Owen Masback

12
Quando ho letto la spiegazione ancora non vedo come StyleSheet.create({styles...})sia migliore / più veloce di {styles...}. Il codice è altrettanto pulito e stai anche usando la denominazione invece di inlining. Qualcuno può far luce su di esso?
freeall

9
StyleSheetfornisce la convalida alla compilazione
Jeevan Takhar

10
Downvoted. Non inserire informazioni irrilevanti ("allontanando gli stili dalla funzione di rendering", ecc.) Nella risposta.
Roymunson

5
Downvoted, la domanda dell'OP era la differenza tra StyleSheet.createe un semplice Object, non inline vs un const al di fuori della classe
quirimmo

56

Non ci sono vantaggi. Periodo.

Mito 1: StyleSheetè più performante

Non c'è assolutamente alcuna differenza di prestazioni tra StyleSheete un oggetto dichiarato all'esterno di render(sarebbe diverso se crei un nuovo oggetto all'interno renderogni volta). La differenza di prestazioni è un mito.

L'origine del mito è probabilmente perché il team di React Native ha provato a farlo, ma non ci sono riusciti. Da nessuna parte nei documenti ufficiali troverai nulla sulle prestazioni: https://facebook.github.io/react-native/docs/stylesheet.html , mentre il codice sorgente indica "non ancora implementato": https://github.com/ facebook / react-native / blob / master / Libraries / StyleSheet / StyleSheet.js # L207

Mito 2: StyleSheetconvalida l'oggetto di stile in fase di compilazione

Questo non è vero. JavaScript normale non può convalidare gli oggetti in fase di compilazione.

Due cose:

  • Viene convalidato in fase di esecuzione, ma lo è anche quando si passa l'oggetto di stile a un componente. Nessuna differenza.
  • Viene convalidato in fase di compilazione se stai usando Flow o TypeScript , ma lo fa una volta passato l'oggetto come prop di stile a un componente, o se hai digitato correttamente l'oggetto di suggerimento come sotto. Nessuna differenza neanche.
const containerStyle: ViewStyle = {
   ...
}

3
Vero. Forse la confusione deriva dalla versione precedente dei loro documenti, che implicava che alla fine avrebbero fatto riferimento agli stili in base all'ID. Questo non è menzionato nei documenti 0.59.
eremzeit

1
THX per demistificare. Ma la domanda è aperta: per cosa?
Vasiliy Vanchuk


Grazie per questa risposta. Merita più voti positivi :)
ThaJay

3
Il mio test indica che non convalida in fase di esecuzione, senza bisogno di passare a un componente, ad esempio, StyleSheet.create( {x:{flex: "1"}} )avrà esito negativo in fase di esecuzione, così come un controllo dattiloscritto su questo al momento della compilazione.
Glenn Lawrence

24

La risposta accettata non è una risposta alla domanda OP.

La domanda non è la differenza tra gli stili inline e quelli constesterni alla classe, ma perché dovremmo usare StyleSheet.createinvece di un semplice oggetto.

Dopo un po 'di ricerche, quello che ho trovato è il seguente (aggiorna se hai informazioni). I vantaggi di StyleSheet.createdovrebbero essere i seguenti:

  1. Valida gli stili
  2. Migliori prestazioni perché crea una mappatura degli stili a un ID, e quindi si riferisce all'interno con questo ID, invece di creare ogni volta un nuovo oggetto. Quindi anche il processo di aggiornamento dei dispositivi è più veloce perché non invii ogni volta tutti i nuovi oggetti.

11
Questi sono miti. Controlla la mia risposta.
Nikola Mihajlović

Se definisco l'oggetto stile al di fuori della classe (o anche come proprietà della classe) verrà creato una volta (o una volta per istanza). Gli stessi oggetti che vengono creati di nuovo sono rilevanti solo all'interno delle funzioni.
ThaJay

Sì per il const, ma la proprietà della classe no. Proprietà di classe statica sì.
quirimmo

5

Si riteneva che l'utilizzo di uno StyleSheet fosse più performante, ed è stato consigliato per questo motivo dal team RN fino alla versione 0.57, ma ora non è più consigliato come correttamente indicato in un'altra risposta a questa domanda.

La documentazione RN ora consiglia StyleSheet per i seguenti motivi, anche se penso che questi motivi si applicherebbero allo stesso modo agli oggetti semplici creati al di fuori della funzione di rendering:

  • Allontanando gli stili dalla funzione di rendering, si semplifica la comprensione del codice.
  • Assegnare un nome agli stili è un buon modo per aggiungere significato ai componenti di basso livello nella funzione di rendering.

Quindi quali sono i possibili vantaggi dell'utilizzo di StyleSheet su oggetti semplici?

1) Nonostante le affermazioni in senso contrario mio test sulla RN v0.59.10 indica che si fa prendere un po 'di convalida quando si chiama StyleSheet.create()e dattiloscritto (e probabilmente di flusso) sarà anche segnalare errori in fase di compilazione. Anche senza il controllo del tempo di compilazione, penso che sia comunque vantaggioso eseguire la convalida in fase di esecuzione degli stili prima che vengano utilizzati per il rendering, in particolare dove i componenti che utilizzano quegli stili potrebbero essere renderizzati in modo condizionale. Ciò consentirà di rilevare tali errori senza dover testare tutti gli scenari di rendering.

2) Dato che StyleSheet è consigliato dal team RN, potrebbero ancora sperare di utilizzare StyleSheet per migliorare le prestazioni in futuro e potrebbero avere in mente anche altri possibili miglioramenti, ad esempio:

3) L'attuale StyleSheet.create()convalida in fase di esecuzione è utile, ma un po 'limitata. Sembra essere limitato al controllo del tipo che si otterrebbe con il flusso o il dattiloscritto, quindi raccoglierà flex: "1"o borderStyle: "rubbish", ma non in width: "rubbish"quanto potrebbe essere una stringa percentuale. È possibile che il team RN possa migliorare tale convalida in futuro controllando cose come stringhe percentuali o limiti di intervallo, oppure potresti includere la StyleSheet.create()tua funzione per eseguire una convalida più ampia.

4) Usando StyleSheet stai forse rendendo più facile la transizione ad alternative / estensioni di terze parti come il foglio di stile reattivo-nativo-esteso che offrono di più.


1

La creazione dei tuoi stili tramite StyleSheet.createpasserà attraverso la convalida solo quando la variabile globale __DEV__è impostata su true (o durante l'esecuzione all'interno di emulatori Android o IOS vedi React Native DEV e variabili PROD )

Il codice sorgente della funzione è piuttosto semplice:

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

Consiglierei di usarlo perché esegue la convalida in fase di esecuzione durante lo sviluppo, inoltre congela l'oggetto.


0

Non ho trovato differenze StyleSheetnell'oggetto tra e normale, ad eccezione della convalida della digitazione in TypeScript.

Ad esempio, questo (nota le differenze di battitura):

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

è uguale a questo:

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,
  },
};
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.