React Native - Qual é a vantagem de usar StyleSheet em vez de um objeto simples?

105

Qual é exatamente a vantagem de usar em StyleSheet.create()relação a um objeto simples?

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

Vs.

const styles = {
  container: {
    flex: 1
  }
}
Corasan
fonte
Recebo suporte VSCode intellisense para propriedades. Esse é o benefício.
helloworld

Respostas:

42

Citando diretamente da seção de comentários de StyleSheet.js do React nativo

Qualidade do código:

  • Ao afastar os estilos da função de renderização, você está tornando o código mais fácil de entender.

  • Nomear os estilos é uma boa maneira de adicionar significado aos componentes de baixo nível na função de renderização.

Atuação:

  • Criar uma folha de estilo a partir de um objeto de estilo torna possível referenciá-lo por ID em vez de criar um novo objeto de estilo a cada vez.

  • Também permite enviar o estilete apenas uma vez pela ponte. Todos os usos subsequentes irão se referir a um id (ainda não implementado).

Além disso, StyleSheet também valida o conteúdo da folha de estilo. Portanto, qualquer erro de propriedade de estilo incorreto é mostrado no momento da compilação, e não no tempo de execução, quando o StyleSheet é realmente implementado.

while1
fonte
46
Os três primeiros pontos são irrelevantes para a técnica do OP de declarar o objeto de estilo como uma const fora da função de renderização.
Owen Masback
12
Quando leio a explicação, ainda não vejo como StyleSheet.create({styles...})é melhor / mais rápido do que {styles...}. O código é igualmente limpo e você também está usando nomenclatura em vez de inlining. Alguém pode lançar alguma luz sobre isso?
freeall
9
StyleSheetfornece validação na compilação
Jeevan Takhar
10
Votos negativos. Não coloque informações irrelevantes ("afastando os estilos da função de renderização", etc.) em sua resposta.
Roymunson
5
Em votação negativa, a questão do OP era a diferença entre StyleSheet.createe um Objeto simples, não embutido vs um const fora da classe
quirimmo
56

Não há benefício. Período.

Mito 1: StyleSheettem mais desempenho

Não há absolutamente nenhuma diferença de desempenho entre StyleSheete um objeto declarado fora de render(seria diferente se você estivesse criando um novo objeto dentrorender cada vez). A diferença de desempenho é um mito.

A origem do mito é provavelmente porque a equipe React Native tentou fazer isso, mas não teve sucesso. Em nenhum lugar dos documentos oficiais você encontrará algo sobre desempenho: https://facebook.github.io/react-native/docs/stylesheet.html , enquanto o código-fonte indica "ainda não implementado": https://github.com/ facebook / react-native / blob / master / Libraries / StyleSheet / StyleSheet.js # L207

Mito 2: StyleSheetvalida o objeto de estilo em tempo de compilação

Isso não é verdade. JavaScript simples não pode validar objetos em tempo de compilação.

Duas coisas:

  • Ele é validado em tempo de execução, mas também quando você passa o objeto de estilo para um componente. Sem diferença.
  • Ele valida em tempo de compilação se você estiver usando Flow ou TypeScript , mas o faz assim que você passa o objeto como uma propriedade de estilo para um componente, ou se você digita corretamente um objeto de sugestão como a seguir. Nenhuma diferença também.
const containerStyle: ViewStyle = {
   ...
}
Nikola Mihajlović
fonte
3
Verdade. Talvez a confusão venha da versão anterior de seus documentos, sugerindo que eles acabariam por referenciar estilos por id. Isso não é mencionado nos documentos 0.59.
eremzeit
1
THX para desmistificar. Mas a questão está aberta - para quê?
Vasiliy Vanchuk
1
Mais sobre p2 github.com/facebook/react-native/blob/…
Vasiliy Vanchuk
Obrigado por esta resposta. Ele merece mais
votos positivos
3
Meu teste indica que ele é validado em tempo de execução sem a necessidade de passar para um componente, por exemplo StyleSheet.create( {x:{flex: "1"}} ), falhará em tempo de execução, assim como uma verificação de texto digitado no tempo de compilação.
Glenn Lawrence
24

A resposta aceita não é uma resposta à pergunta do OP.

A questão não é a diferença entre estilos inline e constfora da classe, mas por que devemos usarStyleSheet.create vez de um objeto simples.

Depois de pesquisar um pouco o que encontrei é o seguinte (atualize se você tiver alguma informação). As opções de StyleSheet.createdevem ser as seguintes:

  1. Valida os estilos
  2. Melhores desempenhos porque cria um mapeamento dos estilos para um ID, e depois se refere internamente com este ID, ao invés de criar a cada vez um novo objeto. Portanto, até o processo de atualização de dispositivos é mais rápido porque você não envia todos os novos objetos todas as vezes.
Quirimmo
fonte
11
Esses são mitos. Verifique minha resposta.
Nikola Mihajlović
Se eu definir o objeto de estilo fora da classe (ou mesmo como uma propriedade da classe), ele será criado uma vez (ou uma vez por instância). Os mesmos objetos sendo criados novamente são relevantes apenas dentro das funções.
ThaJay de
Sim, para const, mas não propriedade de classe. Propriedade de classe estática sim.
quirimmo
5

Ela costumava ser considerado que o uso de uma folha de estilo era mais alto desempenho, e foi recomendado por esta razão pela equipe RN-se até a versão 0.57, mas já não é recomendado como corretamente apontou em outra resposta a esta pergunta.

A documentação do RN agora recomenda StyleSheet pelos seguintes motivos, embora eu ache que esses motivos se aplicam igualmente a objetos simples que são criados fora da função de renderização:

  • Ao afastar os estilos da função de renderização, você está tornando o código mais fácil de entender.
  • Nomear os estilos é uma boa maneira de adicionar significado aos componentes de baixo nível na função de renderização.

Então, quais são os possíveis benefícios do uso de StyleSheet em vez de objetos simples?

1) Apesar das afirmações em contrário meu teste no RN v0.59.10 indica que você faça obter alguma validação quando chamado StyleSheet.create()e typescript (e provavelmente fluir) também irá reportar erros em tempo de compilação. Mesmo sem a verificação do tempo de compilação, acho que ainda é benéfico fazer a validação de tempo de execução de estilos antes serem usados ​​para renderização, particularmente onde componentes que usam esses estilos podem ser renderizados condicionalmente. Isso permitirá que tais erros sejam detectados sem a necessidade de testar todos os cenários de renderização.

2) Dado que o StyleSheet é recomendado pela equipe RN, eles ainda podem ter esperanças de usar o StyleSheet para melhorar o desempenho no futuro, e podem ter outras melhorias possíveis em mente, por exemplo:

3) A StyleSheet.create()validação de tempo de execução atual é útil, mas um pouco limitada. Parece estar restrito à verificação de tipo que você obteria com o fluxo ou o texto digitado, então pegará digamos flex: "1"ou borderStyle: "rubbish", mas não width: "rubbish"porque poderia ser uma string de porcentagem. É possível que a equipe RN possa melhorar essa validação no futuro, verificando coisas como strings de porcentagem ou limites de intervalo, ou você pode quebrarStyleSheet.create() em sua própria função para fazer uma validação mais extensa.

4) Ao usar o StyleSheet, você talvez esteja facilitando a transição para alternativas / extensões de terceiros, como a folha de estilo react-native-extended-style que oferece mais.

Glenn Lawrence
fonte
1

A criação de seus estilos via StyleSheet.createpassará pela validação apenas quando a variável global __DEV__for definida como verdadeira (ou durante a execução dentro de emuladores Android ou IOS, consulte React Native DEV e variáveis ​​PROD )

O código- fonte da função é bastante simples:

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

Eu recomendaria usá-lo porque ele executa a validação em tempo de execução durante o desenvolvimento e também congela o objeto.

bmaggi
fonte
0

Não encontrei nenhuma diferença no meio StyleSheete no objeto simples, exceto na validação de digitação no TypeScript.

Por exemplo, isto (observe as diferenças de digitação):

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

é igual a este:

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
fonte