Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The purpose of StyleSheet.create in React Native

Tags:

react-native

I wanted to ask the community about the changes in StyleSheet.create in React Native.

Before:

I have reviewed the past questions about this topic, such as this question, but they all have been answered pretty a long time ago (apart from this answer, but I wanted to have something definite) and a lot has changed since.

Before StyleSheet was creating a unique id for the styles, mainly for performance optimisations. If you wanted to get the styles out of the created styles object, you should have used the flatten method. The majority of the answers reference this flatten method and you could not access styles property as if it was a normal object.

E.g.

const styles = StyleSheet.create({
  modalContainer: {
    width: 100,
    backgroundColor: 'white',
    padding: 5,
  },

You could not access the padding styles like styles.modalContainer.padding;

Currently:

However, the behaviour of this has changed. This is the source code of StyleSheet from the React Native team. Just copying the create method:

create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
    // 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;
  },
};

Which is just returning the object passed to create without doing anything to it. So you can actually access the styles as styles.modalContainer.padding;

Maybe I don't understand clearly the TODO, but this method has been coded this way at least since RN 0.57 and I don't know whether they are going to change it back.

My question:

Is there any sense in using StyleSheet.create anymore?

Thanks in advance for sharing your opinions!

like image 420
Konstantin Avatar asked Dec 06 '19 11:12

Konstantin


2 Answers

Stylesheet is generally used to create a global style in react native and add it to the respective views which requires to style the objects.

Some widgets like TextInput, Text, Button cannot apply almost all the css styles in the react native.

So, in those cases what you can do is you can wrap those widgets with and then can create global StyleSheets using StyleSheet.create() method to globally use and reduce your headache.

So the conclusion for your question can be summarized as the Stylesheet.create() can be helpful to improve the performance while styling your multiple views using the same style will create a new object every time for each one.

While Stylesheet.create() will act as a single global object for all the views which are using it to style themselves resulting performance/memory optimisation.

like image 62
Jay Mungara Avatar answered Nov 29 '22 22:11

Jay Mungara


I've never heard of this flatten() being necessary like you described. In fact, in the React Native repo in the very first commit, there was an example provided:

Examples/Movies/MovieCell.js:

https://github.com/facebook/react-native/commit/a15603d8f1ecdd673d80be318293cee53eb4475d#diff-4712aeb2165b3c0ce812bef903be3464

In this example, you can see var styles = StyleSheet.create({..}); being used in its present flavor and at that moment in 2016 you can see styles being referenced in the components as styles.styleName.

Additionally in the StyleSheet class here is create from the initial commit:

class StyleSheet {
   static create(obj) {
     var result = {};
     for (var key in obj) {
       StyleSheet.validateStyle(key, obj);
       result[key] = StyleSheetRegistry.registerStyle(obj[key]);
     }
     return result;
   }
// ...
}

As you see, no call to flatten on the initial commit, neither inside the create method, nor from the user using create.

In summary it seems this never changed and you could always access the styles using the dot operator.

As for whether to use it I don't think you have a choice. It clearly has some sort of validation code inside of it, it's also using type checking and the react team recommends using it. I don't see any other methods that do what it does. How could you use the class without create, just using some sort of init or constructor method? I don't see one on the class. There is no StyleSheet({...}); To get obj returned you need to call create.

Your editor could not give you IntelliSense if you strip away the validation behavior and make it a plain object. You won't know when you're making typos or referencing styles that don't exist, you won't have autocompletion. You'd need to create your own interfaces and use TypeScript. Thus you should use create because otherwise at a minimum you're breaking your IDE.

like image 31
tshm001 Avatar answered Nov 29 '22 20:11

tshm001