×
×
whitesmith.co

Styling with React Native

Rui Magalhães

When I first started with React Native I quickly realised a trend of reusing components that would be used multiple times throughout the app.

Based on this approach I quickly ended up with components like TextBold, ButtonBlue, InputBig, etc. This is not that bad of an approach, in my opinion, you have a reusable component that you can stick everywhere you want and if you need some additional style you can always add some inline styling defined on the components that hold them.

But can we do better than this? Yes, I think so.

There are in fact some problems with this approach.
Imagine that you have your TextBoldRed component that you use wherever you need to show some alert info to the user. It might have some styling props like this:

fontWeight: 'bold',  
fontSize: 20,  
color: 'red',  

Great! You have your little component and you can grab it and use it everywhere but as soon as you start placing the component where you need you’ll need to tweak certain aspects and you quickly realize that more style is needed to do that on the parent component. On top of this, and this might be the bigger issue here, chances are that your other text components will share a lot of the same styling code and you’ll be forced to duplicate code.

So, what can you do to improve this?

Object Oriented Styling

My web dev homies at Whitesmith are kind of obsessed with code reusability, dryness and readability. I get them, you would go mad if you didn't when you're targeting 1.000.000 different screen sizes. So while taking my first steps in the web inspired world of React Native I keep questioning them about their trade and they just told me how OOCSS helped them keeping their sanity while styling big projects.

So Instead of writing a bunch tiny reusable atomic components, let's try to write reusable styles and keep the component closed for modification but open for extension.
Using the previous example we can decouple our styling like this:

const textStyles = {  
    large: {      
        fontSize: 20,
    },  
    danger: {     
        fontWeight: 'bold',      
        color: 'red'   
    },
}

And now our component can be written in this simple way:

<Text style={[large, danger]}>  
    This message is very bad.
</Text>  

Now, even in this tiny and very simple example, we have a bit more flexibility and clarity.
If you need to change your style along the way it will not be painful at all cause your styling is well defined and encapsulated. Should danger messages now be displayed in an orange color instead of red? Easy. New typeface? Done. Need a large success version? Extend it like the danger one!

Separation of Concerns

The only thing that we couldn’t solve completely with this approach is the positioning of these components.
My friend Renato told me about Bruce Lee's analogy of water filling the cup when trying to explain to me how I should separate layout from content, skeleton from skin:

You must be shapeless, formless, like water. When you pour water in a cup, it becomes the cup. When you pour water in a bottle, it becomes the bottle. When you pour water in a teapot, it becomes the teapot. Water can drip and it can crash. Become like water my friend.

The problem is that Renato has grown up inside a browser where <div> are for free. On the native world, this is not necessarily true, in order to do this without recurring to inline styling for spacing the margins, you’ll need to place more views to function as containers to keep your components where you want and this can have an impact on performance.
Considering this, I’m still keeping my margin spaces on inline styles. It’s not perfect and surely not that pretty but it’s a price I’m willing to pay to avoid unnecessary views. Using inline styles just for margin spaces we can then arrive at something like this:

<Text style={[bold, danger, styles.textMargin]}>  
    This message is very bad.
</Text>

const styles = {  
    textMargin: {       
        marginBottom: 40,       
        marginRight: 20,        
        marginLeft: 20  
    }
}

I’m now maintaining two apps written in React Native, one styled with this approach and one with the first that I mentioned and I found this last one to be easier to understand and maintain.

What about you, how do you handle style in your React Native apps?

I'm very thankful for working with amazing people that push me to improve on a daily basis. Special thanks to José and to Renato for the help on editing this post. Lots of the words on this post came actually from them.



References: Harry Roberts has a bible on Object Oriented CSS if you're interested on that make sure you give it a read.


Subscribe to our newsletter

Would you like to receive more posts of this kind in your Inbox?