React Native - Jaka jest korzyść z używania StyleSheet w porównaniu z prostym obiektem?

105

Jaka jest dokładnie korzyść z używania w StyleSheet.create()porównaniu do zwykłego przedmiotu?

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

Vs.

const styles = {
  container: {
    flex: 1
  }
}
corasan
źródło
Dostaję obsługę technologii Intellisense VSCode dla właściwości. To jest korzyść.
helloworld

Odpowiedzi:

42

Cytując bezpośrednio z sekcji komentarzy w StyleSheet.js w React native

Jakość kodu:

  • Odsuwając style od funkcji renderowania, ułatwiasz zrozumienie kodu.

  • Nazywanie stylów jest dobrym sposobem nadania znaczenia komponentom niskiego poziomu w funkcji renderowania.

Występ:

  • Tworzenie arkusza stylów z obiektu stylu umożliwia odwoływanie się do niego przez identyfikator zamiast tworzenia za każdym razem nowego obiektu stylu.

  • Pozwala również na jednorazowe przesłanie stylu przez most. Wszystkie kolejne zastosowania będą dotyczyły identyfikatora (jeszcze nie zaimplementowany).

StyleSheet sprawdza również zawartość arkusza stylów. Tak więc każdy błąd związany z nieprawidłową właściwością stylu jest wyświetlany w czasie kompilacji, a nie w czasie wykonywania, gdy arkusz StyleSheet jest faktycznie implementowany.

while1
źródło
46
Pierwsze trzy wypunktowania nie mają znaczenia dla techniki OP, polegającej na deklarowaniu obiektu stylu jako stałej poza funkcją renderowania.
Owen Masback
12
Kiedy czytam wyjaśnienie, nadal nie widzę, co StyleSheet.create({styles...})jest lepsze / szybsze niż {styles...}. Kod jest równie czysty, a zamiast wstawiania używasz również nazewnictwa. Czy ktoś może rzucić na to trochę światła?
cały
9
StyleSheetzapewnia walidację podczas kompilacji
Jeevan Takhar
10
Głosowano w dół. Nie umieszczaj w odpowiedzi nieistotnych informacji („odsuwając style od funkcji renderowania” itp.).
Roymunson
5
Po odrzuceniu, kwestią OP była różnica między StyleSheet.createzwykłym Object, not inline a const poza klasą
quirimmo
56

Nie ma żadnej korzyści. Kropka.

Mit 1: StyleSheetjest bardziej wydajny

Nie ma absolutnie żadnej różnicy w wydajności między StyleSheetobiektem zadeklarowanym na zewnątrz a render(byłoby inaczej, gdyby za renderkażdym razem tworzył nowy obiekt wewnątrz ). Różnica w wydajności to mit.

Pochodzenie mitu jest prawdopodobne, ponieważ zespół React Native próbował to zrobić, ale nie udało im się to. Nigdzie w oficjalnych dokumentach nie znajdziesz nic o wydajności: https://facebook.github.io/react-native/docs/stylesheet.html , podczas gdy kod źródłowy stwierdza, że ​​„jeszcze nie zaimplementowano”: https://github.com/ facebook / reag-native / blob / master / Libraries / StyleSheet / StyleSheet.js # L207

Mit 2: StyleSheetsprawdza poprawność obiektu stylu w czasie kompilacji

To nie jest prawda. Zwykły JavaScript nie może sprawdzać poprawności obiektów w czasie kompilacji.

Dwie rzeczy:

  • Sprawdza się w czasie wykonywania, ale tak samo dzieje się podczas przekazywania obiektu stylu do komponentu. Bez różnicy.
  • Sprawdza poprawność w czasie kompilacji, jeśli używasz Flow lub TypeScript , ale tak samo dzieje się, gdy przekażesz obiekt jako właściwość stylu do komponentu lub jeśli poprawnie wpiszesz obiekt podpowiedzi, jak poniżej. Nie ma też różnicy.
const containerStyle: ViewStyle = {
   ...
}
Nikola Mihajlović
źródło
3
Prawdziwe. Być może zamieszanie wynika z wcześniejszej wersji ich dokumentów, co sugeruje, że ostatecznie zamierzali odwoływać się do stylów za pomocą id. To nie jest wspomniane w 0.59 docs.
eremzeit
1
THX za demistyfikację. Ale pytanie jest otwarte - po co?
Vasiliy Vanchuk
1
Plus o p2 github.com/facebook/react-native/blob/…
Vasiliy Vanchuk
Dziękuję za tę odpowiedź. Zasługuje na więcej głosów :)
ThaJay
3
Moje badania wskazują, że robi validate przy starcie bez konieczności przejść do komponentu, np StyleSheet.create( {x:{flex: "1"}} )zawiedzie w czasie wykonywania, podobnie jak kontrola maszynopis na to w czasie kompilacji.
Glenn Lawrence,
24

Przyjęta odpowiedź nie jest odpowiedzią na pytanie PO.

Nie chodzi o różnicę między stylami w wierszu a stylami constzewnętrznymi, ale dlaczego powinniśmy używać StyleSheet.createzamiast zwykłego obiektu.

Po krótkiej analizie tego, co znalazłem, jest następujące (zaktualizuj, jeśli masz jakieś informacje). Zalety StyleSheet.createpowinny być następujące:

  1. Sprawdza style
  2. Lepiej działa, ponieważ tworzy mapowanie stylów do identyfikatora, a następnie odwołuje się do środka z tym identyfikatorem, zamiast tworzyć za każdym razem nowy obiekt. Więc nawet proces aktualizacji urządzeń jest szybszy, ponieważ nie wysyłasz za każdym razem wszystkich nowych obiektów.
quirimmo
źródło
11
To są mity. Sprawdź moją odpowiedź.
Nikola Mihajlović
Jeśli zdefiniuję obiekt stylu poza klasą (lub nawet jako właściwość klasy), zostanie on utworzony raz (lub raz na instancję). Te same obiekty, które są tworzone ponownie, mają znaczenie tylko w funkcjach.
ThaJay
Tak dla const, ale właściwość klasy nie. Właściwość klasy statycznej tak.
quirimmo,
5

Kiedyś uważano, że używanie arkusza StyleSheet było bardziej wydajne i było zalecane z tego powodu przez zespół RN aż do wersji 0.57, ale teraz nie jest już zalecane, jak poprawnie wskazano w innej odpowiedzi na to pytanie.

Dokumentacja RN zaleca teraz arkusz StyleSheet z następujących powodów, chociaż myślę, że te powody miałyby zastosowanie w równym stopniu do zwykłych obiektów, które są tworzone poza funkcją renderowania:

  • Odsuwając style od funkcji renderowania, ułatwiasz zrozumienie kodu.
  • Nazywanie stylów jest dobrym sposobem nadania znaczenia komponentom niskiego poziomu w funkcji renderowania.

Więc jak myślę, jakie możliwe zalety używania arkusza StyleSheet nad zwykłymi obiektami?

1) Pomimo twierdzeń przeciwnych moje badania na RN v0.59.10 oznacza, że zrobić trochę walidacji podczas wywoływania StyleSheet.create()i maszynopis (i prawdopodobnie przepływu) będzie także zgłaszać błędy w czasie kompilacji. Myślę, że nawet bez sprawdzania czasu kompilacji nadal korzystne jest sprawdzanie poprawności stylów w czasie wykonywania, zanim zostaną one użyte do renderowania, zwłaszcza gdy komponenty używające tych stylów mogą być warunkowo renderowane. Umożliwi to wychwycenie takich błędów bez konieczności testowania wszystkich scenariuszy renderowania.

2) Biorąc pod uwagę, że StyleSheet jest zalecany przez zespół RN, mogą nadal mieć nadzieję na wykorzystanie StyleSheet do poprawy wydajności w przyszłości, a także mogą mieć na uwadze inne możliwe ulepszenia, na przykład:

3) Bieżąca StyleSheet.create()walidacja w czasie wykonywania jest przydatna, ale nieco ograniczona. Wydaje się, że ogranicza się to do sprawdzania typu, które można uzyskać za pomocą przepływu lub skryptu, więc wybierze powiedz flex: "1"lub borderStyle: "rubbish", ale nie, width: "rubbish"ponieważ może to być ciąg procentowy. Jest możliwe, że zespół RN może ulepszyć taką walidację w przyszłości, sprawdzając takie rzeczy, jak ciągi procentowe lub limity zakresów, lub możesz zawinąć StyleSheet.create()swoją własną funkcję, aby wykonać bardziej rozbudowaną walidację.

4) Używając arkusza StyleSheet, być może ułatwiasz przejście na alternatywne rozwiązania / rozszerzenia innych firm, takie jak reakcja-natywny-rozszerzony-arkusz stylów, które oferują więcej.

Glenn Lawrence
źródło
1

Tworzenie twoich stylów za pomocą StyleSheet.createprzejdzie przez walidację tylko wtedy, gdy zmienna globalna __DEV__jest ustawiona na true (lub podczas pracy w emulatorach Androida lub IOS zobacz zmienne React Native DEV i PROD )

Kod źródłowy funkcji jest dość prosty:

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

Poleciłbym go używać, ponieważ wykonuje walidację w czasie wykonywania podczas programowania, a także zamraża obiekt.

bmaggi
źródło
0

Nie znalazłem żadnych różnic w między StyleSheeti zwykłym obiekcie, z wyjątkiem sprawdzania poprawności wpisywania w TypeScript.

Na przykład to (zwróć uwagę na różnice w pisaniu):

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

równa się temu:

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
źródło