141

What exactly is the benefit of using StyleSheet.create() vs a plain object?

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

Vs.

const styles = {
  container: {
    flex: 1
  }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
corasan
  • 2,636
  • 3
  • 24
  • 41
  • 2
    I get VSCode intellisense support for properties. That's the benefit. – helloworld Aug 09 '20 at 14:57
  • When used with ``react-native-web``, ``StyleSheet.create`` creates a new CSS class whereas a vanilla object gets attached as inline styles – Tracer69 Mar 02 '22 at 18:52

8 Answers8

107

There is no benefit. Period.

Myth 1: StyleSheet is more performant

There is absolutely no performance difference between StyleSheet and an object declared outside of render (it would be different if you're creating a new object inside render every time). The performance difference is a myth.

The origin of the myth is likely because React Native team tried to do this, but they weren't successful. Nowhere in the official docs you will find anything about performance: https://facebook.github.io/react-native/docs/stylesheet.html, while source code states "not implemented yet": https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/StyleSheet.js#L207

Myth 2: StyleSheet validates style object at compile time

This is not true. Plain JavaScript can't validate objects at compile time.

Two things:

  • It does validate at runtime, but so does when you pass the style object to a component. No difference.
  • It does validate at compile time if you're using Flow or TypeScript, but so does once you pass the object as a style prop to a component, or if you properly typehint object like below. No difference either.
const containerStyle: ViewStyle = {
   ...
}
Nikola Mihajlović
  • 2,286
  • 2
  • 19
  • 23
50

Quoting directly from comment section of StyleSheet.js of React native

Code quality:

  • By moving styles away from the render function, you're making the code easier to understand.

  • Naming the styles is a good way to add meaning to the low level components in the render function.

Performance:

  • Making a stylesheet from a style object makes it possible to refer to it by ID instead of creating a new style object every time.

  • It also allows to send the style only once through the bridge. All subsequent uses are going to refer an id (not implemented yet).

Also StyleSheet validates your stylesheet content as well. So any error of incorrect style property is shown at time of compiling rather than at runtime when StyleSheet is actually implemented.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
while1
  • 3,320
  • 19
  • 12
  • 1
    I see, I was wondering because I can just use an object so what's the point of StyleSheet. Also, is inline better than StyleSheet when it comes to performance? Thank you for the answer :) – corasan Aug 15 '16 at 18:06
  • 3
    No. Inline is not efficient as well. It is similar to using normal object. Because with inline style as well react native will need to send more data to React native bridge as compared to stylesheet. Which is not good for performance – while1 Aug 15 '16 at 18:09
  • 52
    The first three bullet points are irrelevant of OP's technique of declaring the style object as a const outside the render function. – Owen Masback Jul 03 '17 at 23:30
  • 1
    My thoughts as Owen exactly. I worked through tutorials that just used the OP's technique, and then I came across this stylesheet function and couldn't figure out what the point was. So the only perk is the compile-time validation. I'd appreciate if someone can elaborate on the last bullet point. – CopyJosh Nov 30 '17 at 17:28
  • 12
    When I read the explanation I still don't see how `StyleSheet.create({styles...})` is better/faster than `{styles...}`. The code is just as clean, and you're also using naming instead of inlining. Can anyone shed some light on it? – freeall Jan 04 '18 at 10:59
  • 9
    `StyleSheet` provides validation at compilation – Jeevan Takhar Jun 06 '18 at 16:07
  • 14
    Downvoted. Don't put irrelevant information ("by moving styles away from the render function", etc.) in your answer. – Foobar Aug 19 '18 at 22:29
  • 6
    Downvoted, the question of the OP was the difference between `StyleSheet.create` and a plain Object, not inline vs a const outside the class – quirimmo Oct 03 '18 at 15:19
  • Downvoted for not giving a relevant answer. There are no differences between them except of typing normalization in TypeScript. – Slavik Meltser Mar 19 '20 at 06:29
  • react-native docs [removed](https://reactnative.dev/docs/stylesheet) the bullet point referencing "send the style only once through the bridge". – jchook May 23 '20 at 20:48
  • If you're using react-native-web (for example the expo bare workflow and yarn web script), there is a big difference. StyleSheet.create will generate atomic css classes whereas a regular style object will result in inline styles: https://stackoverflow.com/questions/63585152/how-to-generate-class-names-instead-of-inline-styles-for-react-native-web – sschottler Oct 13 '20 at 15:43
25

The accepted answer is not an answer to the OP question.

The question is not the difference between inline styles and a const outside the class, but why we should use StyleSheet.create instead of a plain object.

After a bit of researching what I found is the following (please update if you have any info). The advatanges of StyleSheet.create should be the following:

  1. It validates the styles
  2. Better perfomances because it creates a mapping of the styles to an ID, and then it refers inside with this ID, instead of creating every time a new object. So even the process of updating devices is faster because you don't send everytime all the new objects.
quirimmo
  • 9,800
  • 3
  • 30
  • 45
10

It used to be considered that using a StyleSheet was more performant, and was recommended for this reason by the RN team up until version 0.57, but it is now no longer recommended as correctly pointed out in another answer to this question.

The RN documentation now recommends StyleSheet for the following reasons, though I think these reasons would apply equally to plain objects that are created outside of the render function:

  • By moving styles away from the render function, you're making the code easier to understand.
  • Naming the styles is a good way to add meaning to the low level components in the render function.

So what do I think are the possible benefits of using StyleSheet over plain objects?

1) Despite claims to the contrary my testing on RN v0.59.10 indicates that you do get some validation when calling StyleSheet.create() and typescript (and probably flow) will also report errors at compile time. Even without compile time checking I think it's still beneficial to do run time validation of styles before they are used for rendering, particularly where components that use those styles could be conditionally rendered. This will allow such errors to be picked up without having to test all rendering scenarios.

2) Given that StyleSheet is recommended by the RN team they may still have hopes of using StyleSheet to improve performance in future, and they may have other possible improvements in mind as well, for example:

3) The current StyleSheet.create() run-time validation is useful, but a bit limited. It seems to be restricted to the type checking that you would get with flow or typescript, so will pick up say flex: "1" or borderStyle: "rubbish", but not width: "rubbish" as that could be a percentage string. It's possible that the RN team may improve such validation in future by checking things like percentage strings, or range limits, or you could wrap StyleSheet.create() in your own function to do that more extensive validation.

4) By using StyleSheet you are perhaps making it easier to transition to third party alternatives/extensions like react-native-extended-stylesheet that offer more.

Glenn Lawrence
  • 2,844
  • 1
  • 32
  • 38
7

So, today, September of 2021, after reading all the answers and doing some researches, I created a summary about using Stylesheet instead of a plain object.

  1. Based on React Documentation, you should use the stylesheet when the complexity starts to grow.

The style prop can be a plain old JavaScript object. That's what we usually use for example code. As a component grows in complexity, it is often cleaner to use StyleSheet.create to define several styles in one place.

  1. In the simulator, when using stylesheet will display an ERROR, and when using the plain object will display only a WARNING.
  2. Based on item 2, it looks like it has some validation while compiling. (A lot of people say that’s a myth)
  3. If you need to migrate for a third-party library in the future, for some of them like react-native-extended-stylesheet, if you are using stylesheet, it will be easier.
  4. You have some methods and properties that boost the development. For example, the property StyleSheet.absoluteFill will do position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, or the method compose() will allow you to combine two styles, overriding it.

P.S.: The performance answer looks to be a myth.

My opinion?

Based on item 2 and 5, go to stylesheet instead of plain objects.

Rafael Perozin
  • 573
  • 7
  • 20
3

I did not find any differences between StyleSheet and plain object, except of typing validation in TypeScript.

For example, this (note the typing differences):

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

equals to this:

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
  • 9,712
  • 3
  • 47
  • 48
1

Creating your styles via StyleSheet.create will pass though validation only when global variable __DEV__ is set to true (or while running inside Android or IOS emulators see React Native DEV and PROD variables)

The function source code is pretty 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;
}

I would recommend using it because it performs run-time validation during development, also it freezes the object.

bmaggi
  • 2,908
  • 1
  • 19
  • 16
1

i know that this is a really late answer, but I've read that it shows you errors and provides auto completion in editors when you use StyleSheet.

mouhib
  • 85
  • 1
  • 8