React Native: ¿cuál es el beneficio de usar StyleSheet frente a un objeto simple?

105

¿Cuál es exactamente el beneficio de usar StyleSheet.create()frente a un objeto simple?

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

Vs.

const styles = {
  container: {
    flex: 1
  }
}
corasan
fuente
Obtengo compatibilidad con VSCode intellisense para propiedades. Ese es el beneficio.
helloworld

Respuestas:

42

Citando directamente desde la sección de comentarios de StyleSheet.js de React native

Calidad del código:

  • Al alejar los estilos de la función de renderizado, hace que el código sea más fácil de entender.

  • Nombrar los estilos es una buena manera de agregar significado a los componentes de bajo nivel en la función de renderizado.

Actuación:

  • Crear una hoja de estilo a partir de un objeto de estilo permite hacer referencia a ella por ID en lugar de crear un nuevo objeto de estilo cada vez.

  • También permite enviar el estilo solo una vez a través del puente. Todos los usos posteriores se referirán a una identificación (aún no implementada).

Además, StyleSheet también valida el contenido de su hoja de estilo. Por lo tanto, cualquier error de propiedad de estilo incorrecta se muestra en el momento de la compilación en lugar de en el tiempo de ejecución cuando StyleSheet está realmente implementado.

while1
fuente
46
Los primeros tres puntos son irrelevantes de la técnica de OP de declarar el objeto de estilo como una constante fuera de la función de render.
Owen Masback
12
Cuando leo la explicación, todavía no veo cómo StyleSheet.create({styles...})es mejor / más rápido que {styles...}. El código es igual de limpio y también está usando nombres en lugar de inlining. ¿Alguien puede arrojar algo de luz sobre esto?
freeall
9
StyleSheetproporciona validación en la compilación
Jeevan Takhar
10
Voto en contra. No coloque información irrelevante ("alejando estilos de la función de renderizado", etc.) en su respuesta.
Roymunson
5
Votado en contra, la pregunta del OP era la diferencia entre StyleSheet.createun Objeto simple, no en línea frente a una constante fuera de la clase
quirimmo
56

No hay ningún beneficio. Período.

Mito 1: StyleSheetes más eficaz

No hay absolutamente ninguna diferencia de rendimiento entre StyleSheetun objeto declarado fuera de render(sería diferente si está creando un nuevo objeto dentro rendercada vez). La diferencia de rendimiento es un mito.

El origen del mito probablemente se deba a que el equipo de React Native intentó hacer esto, pero no tuvo éxito. En ninguna parte de los documentos oficiales encontrará nada sobre el rendimiento: https://facebook.github.io/react-native/docs/stylesheet.html , mientras que el código fuente indica "aún no implementado": https://github.com/ facebook / react-native / blob / master / Bibliotecas / StyleSheet / StyleSheet.js # L207

Mito 2: StyleSheetvalida el objeto de estilo en tiempo de compilación

Esto no es verdad. JavaScript simple no puede validar objetos en tiempo de compilación.

Dos cosas:

  • Se valida en tiempo de ejecución, pero también lo hace cuando pasa el objeto de estilo a un componente. Ninguna diferencia.
  • Se valida en tiempo de compilación si está usando Flow o TypeScript , pero también lo hace una vez que pasa el objeto como un accesorio de estilo a un componente, o si escribe correctamente el objeto como se muestra a continuación. Tampoco hay diferencia.
const containerStyle: ViewStyle = {
   ...
}
Nikola Mihajlović
fuente
3
Cierto. Quizás la confusión proviene de la versión anterior de sus documentos, lo que implica que eventualmente iban a hacer referencia a estilos por id. Eso no se menciona en los documentos 0.59.
eremzeit
1
THX para desmitificar. Pero la pregunta está abierta: ¿para qué?
Vasiliy Vanchuk
1
Más sobre p2 github.com/facebook/react-native/blob/…
Vasiliy Vanchuk
Gracias por esta respuesta. Se merece más votos a favor :)
ThaJay
3
Mi prueba indica que se hace validar en tiempo de ejecución sin necesidad de pasar a un componente, por ejemplo, StyleSheet.create( {x:{flex: "1"}} )se producirá un error en tiempo de ejecución, al igual que un cheque en este manuscrito en tiempo de compilación.
Glenn Lawrence
24

La respuesta aceptada no es una respuesta a la pregunta de OP.

La pregunta no es la diferencia entre estilos en línea y constfuera de la clase, sino por qué deberíamos usar en StyleSheet.createlugar de un objeto simple.

Después de investigar un poco, lo que encontré es lo siguiente (actualice si tiene alguna información). Las ventajas de StyleSheet.createdeberían ser las siguientes:

  1. Valida los estilos
  2. Mejor rendimiento porque crea un mapeo de los estilos a una ID, y luego se refiere al interior con esta ID, en lugar de crear cada vez un nuevo objeto. Entonces, incluso el proceso de actualización de dispositivos es más rápido porque no envía cada vez todos los objetos nuevos.
quirimmo
fuente
11
Estos son mitos. Comprueba mi respuesta.
Nikola Mihajlović
Si defino el objeto de estilo fuera de la clase (o incluso como una propiedad de clase), se creará una vez (o una vez por instancia). Los mismos objetos que se crean nuevamente solo son relevantes dentro de las funciones.
ThaJay
Sí, por la constante, pero la propiedad de clase no. Propiedad de clase estática, sí.
quirimmo
5

Antes se consideraba que el uso de una StyleSheet era más eficaz y, por esta razón, el equipo de RN lo recomendaba hasta la versión 0.57, pero ahora ya no se recomienda como se señaló correctamente en otra respuesta a esta pregunta.

La documentación de RN ahora recomienda StyleSheet por las siguientes razones, aunque creo que estas razones se aplicarían igualmente a los objetos simples que se crean fuera de la función de renderizado:

  • Al alejar los estilos de la función de renderizado, hace que el código sea más fácil de entender.
  • Nombrar los estilos es una buena manera de agregar significado a los componentes de bajo nivel en la función de renderizado.

Entonces, ¿cuáles creo que son los posibles beneficios de usar StyleSheet sobre objetos simples?

1) A pesar de las afirmaciones en contrario mis pruebas en RN v0.59.10 indica que se hace conseguir un poco de validación al llamar StyleSheet.create()y mecanografiado (y probablemente de flujo) también informará de errores en tiempo de compilación. Incluso sin comprobar el tiempo de compilación, creo que sigue siendo beneficioso realizar la validación de los estilos en tiempo de ejecución antes de que se utilicen para el renderizado, especialmente cuando los componentes que utilizan esos estilos podrían renderizarse condicionalmente. Esto permitirá detectar dichos errores sin tener que probar todos los escenarios de renderizado.

2) Dado que el equipo de RN recomienda StyleSheet, es posible que aún tengan esperanzas de usar StyleSheet para mejorar el rendimiento en el futuro, y es posible que también tengan otras posibles mejoras en mente, por ejemplo:

3) La StyleSheet.create()validación en tiempo de ejecución actual es útil, pero un poco limitada. Parece estar restringido a la verificación de tipos que obtendría con el flujo o el mecanografiado, por lo que seleccionará digamos flex: "1"o borderStyle: "rubbish", pero no, width: "rubbish"ya que podría ser una cadena de porcentaje. Es posible que el equipo de RN pueda mejorar dicha validación en el futuro verificando cosas como cadenas de porcentaje o límites de rango, o podría ajustar StyleSheet.create()su propia función para hacer esa validación más extensa.

4) Al usar StyleSheet, quizás esté facilitando la transición a alternativas / extensiones de terceros como react-native-extended-stylesheet que ofrecen más.

Glenn Lawrence
fuente
1

La creación de sus estilos a través StyleSheet.createpasará la validación solo cuando la variable global __DEV__se establezca en verdadero (o mientras se ejecuta dentro de los emuladores de Android o IOS, consulte React Native DEV y PROD variables )

El código fuente de la función es bastante 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;
}

Recomendaría usarlo porque realiza una validación en tiempo de ejecución durante el desarrollo, también congela el objeto.

bmaggi
fuente
0

No encontré ninguna diferencia en el StyleSheetobjeto intermedio y simple, excepto en la validación de escritura en TypeScript.

Por ejemplo, esto (tenga en cuenta las diferencias de escritura):

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

es igual a esto:

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,
  },
};
Fundidor Slavik
fuente