React Native - в чем преимущество использования StyleSheet по сравнению с обычным объектом?


105

В чем именно преимущество использования StyleSheet.create()простого объекта?

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

Vs.

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

Я получаю поддержку VSCode intellisense для свойств. Это преимущество.
helloworld

Ответы:


42

Цитата непосредственно из раздела комментариев StyleSheet.js в React native

Качество кода:

  • Убирая стили из функции рендеринга, вы упрощаете понимание кода.

  • Именование стилей - хороший способ добавить смысла компонентам низкого уровня в функции рендеринга.

Производительность:

  • Создание таблицы стилей из объекта стиля позволяет ссылаться на него по идентификатору вместо того, чтобы каждый раз создавать новый объект стиля.

  • Это также позволяет отправить стиль только один раз через мост. Все последующие использования будут ссылаться на идентификатор (еще не реализован).

Также StyleSheet проверяет содержимое вашей таблицы стилей. Таким образом, любая ошибка неправильного свойства стиля отображается во время компиляции, а не во время выполнения, когда таблица стилей фактически реализована.


46
Первые три пункта не имеют отношения к технике OP по объявлению объекта стиля как константы вне функции рендеринга.
Owen Masback

12
Когда я читаю объяснение, я все еще не понимаю, что StyleSheet.create({styles...})лучше / быстрее чем {styles...}. Код такой же чистый, и вы также используете именование вместо встраивания. Кто-нибудь может пролить свет на это?
freeall 04

9
StyleSheetобеспечивает проверку при компиляции
Дживан Тахар

10
Проголосовали против. Не помещайте в ответ нерелевантную информацию («убрав стили из функции рендеринга» и т. Д.).
Роймунсон

5
Проголосовано против, вопрос OP заключался в разнице между StyleSheet.createи простым объектом, а не встроенным и
константой

57

Нет никакой пользы. Период.

Миф 1: StyleSheetболее производительный

Нет абсолютно никакой разницы в производительности между StyleSheetобъектом, объявленным вне render(это было бы иначе, если бы вы renderкаждый раз создавали новый объект внутри ). Разница в производительности - это миф.

Возникновение мифа, вероятно, связано с тем, что команда React Native пыталась это сделать, но безуспешно. В официальных документах вы не найдете ничего о производительности: https://facebook.github.io/react-native/docs/stylesheet.html , а в исходном коде указано «еще не реализовано»: https://github.com/ facebook / react-native / blob / master / Libraries / StyleSheet / StyleSheet.js # L207

Миф 2: StyleSheet проверяет объект стиля во время компиляции

Это неправда. Обычный JavaScript не может проверять объекты во время компиляции.

Две вещи:

  • Он действительно проверяется во время выполнения, но то же самое происходит при передаче объекта стиля компоненту. Нет разницы.
  • Он действительно проверяется во время компиляции, если вы используете Flow или TypeScript , но то же самое происходит после того, как вы передаете объект в качестве опоры стиля компоненту или если вы правильно набираете объект подсказки, как показано ниже. Никакой разницы.
const containerStyle: ViewStyle = {
   ...
}

3
Правда. Возможно, путаница связана с более ранней версией их документов, подразумевающей, что они в конечном итоге собирались ссылаться на стили по идентификатору. Это не упоминается в документации 0.59.
eremzeit

1
THX для демистификации. Но вопрос открыт - зачем?
Василий


Спасибо за этот ответ. Это заслуживает большего количества голосов :)
ThaJay

3
Мое тестирование показывает, что он действительно проверяется во время выполнения без необходимости перехода к компоненту, например, StyleSheet.create( {x:{flex: "1"}} )не удастся во время выполнения, как и проверка машинописного текста во время компиляции.
Гленн Лоуренс

24

Принятый ответ не является ответом на вопрос OP.

Вопрос не в разнице между встроенными стилями и constвнешними стилями, а в том, почему мы должны использовать StyleSheet.createвместо простого объекта.

После небольшого исследования я обнаружил следующее (пожалуйста, обновите, если у вас есть какая-либо информация). Преимущества StyleSheet.createдолжны быть следующими:

  1. Проверяет стили
  2. Лучшая производительность, потому что он создает сопоставление стилей с идентификатором, а затем обращается внутрь с этим идентификатором, вместо того, чтобы каждый раз создавать новый объект. Таким образом, даже процесс обновления устройств происходит быстрее, потому что вы не отправляете каждый раз все новые объекты.

11
Это мифы. Проверьте мой ответ.
Никола Михайлович

Если я определю объект стиля вне класса (или даже как свойство класса), он будет создан один раз (или один раз для каждого экземпляра). Те же самые объекты, которые создаются снова, актуальны только внутри функций.
ThaJay,

Да для константы, но свойства класса нет. Свойство статического класса да.
quirimmo

5

Раньше считали , что с помощью STYLESHEET был более производительным, и был рекомендован по этой причине по RN команды вплоть до версии 0.57, но она теперь уже не рекомендуется , так как правильно указал в другой ответ на этот вопрос.

Документация RN теперь рекомендует StyleSheet по следующим причинам, хотя я думаю, что эти причины в равной степени применимы к простым объектам, которые создаются вне функции рендеринга:

  • Убирая стили из функции рендеринга, вы упрощаете понимание кода.
  • Именование стилей - хороший способ добавить смысла компонентам низкого уровня в функции рендеринга.

Итак, каковы, на мой взгляд , возможные преимущества использования StyleSheet по сравнению с простыми объектами?

1) Несмотря на утверждения об обратном, мое тестирование на RN v0.59.10 показывает, что вы действительно получаете некоторую проверку при вызове, StyleSheet.create()и машинописный текст (и, вероятно, поток) также будет сообщать об ошибках во время компиляции. Я думаю, что даже без проверки времени компиляции все еще полезно выполнять проверку стилей во время выполнения перед они будут использоваться для рендеринга, особенно когда компоненты, использующие эти стили, могут быть условно визуализированы. Это позволит выявить такие ошибки без необходимости тестирования всех сценариев рендеринга.

2) Учитывая , что StyleSheet будет рекомендован командой RN , они могут по- прежнему есть надежда , используя таблицу стилей для повышения производительности в будущем, и они могут иметь другие возможные улучшения в виде , как хорошо, например:

3) Текущая StyleSheet.create()проверка времени выполнения полезна, но немного ограничена. Кажется, что это ограничено проверкой типа, которую вы получите с потоком или машинописным текстом, поэтому подберет, скажем, flex: "1"или borderStyle: "rubbish", но не width: "rubbish"так, как это может быть процентная строка. Возможно, что команда RN может улучшить такую ​​проверку в будущем, проверяя такие вещи, как процентные строки или пределы диапазона, или вы могли бы обернутьStyleSheet.create() свою собственную функцию, чтобы выполнить эту более обширную проверку.

4) Используя StyleSheet, вы, возможно, упрощаете переход на сторонние альтернативы / расширения, такие как react-native-extended-stylesheet, которые предлагают больше.


1

Создание ваших стилей с помощью StyleSheet.createпройдет проверку, только если для глобальной переменной __DEV__установлено значение true (или при работе внутри эмуляторов Android или IOS см. Переменные React Native DEV и PROD )

Исходный код функции довольно прост:

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

Я бы рекомендовал использовать его, потому что он выполняет проверку во время выполнения во время разработки, а также замораживает объект.


0

Я не обнаружил никаких различий между StyleSheetобъектом и простым объектом, кроме проверки ввода в TypeScript.

Например, это (обратите внимание на различия в типе):

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

равно этому:

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,
  },
};
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.