Managing Styles in React Native

React Native is a framework that allows full-stack developers who are familiar with JavaScript to write feature-rich applications for iPhone and Android devices. Companies such as Facebook, Instagram, and Airbnb are utilizing React Native to write applications that can be written once and exported to run on both platforms with little configuration.

React Native does not force you to learn Objective-C, Swift, or Java making it ideal for a web-developer who wants to build an application that’s on par with some of the best apps on the market. There is some learning curve however, and there’s no “right” way to build an application with React Native. This brief article should serve as a best-practice guide when transitioning from typical CSS styles to React Native StyleSheets.

StyleSheets are not CSS

StyleSheets are like (and not like) the CSS you might be used to writing. For starters, it’s pure JavaScript which forces you to reconfigure some of your muscle memory. For example, in CSS we might write something like this:

.header {
padding: 20px;
margin: 15px 0;
position: absolute;
}

In React Native, there is no such thing as pixels or classes, at least not upfront. Instead, we write our sizes in “units” which are ultimately translated to pixels based on the pixel density of the screen. If we wanted to write the same header in a React Native StyleSheet, it would look something like the following.

import { StyleSheet } from 'react-native';
export default StyleSheet.create({
header: {
padding: 20,
marginTop: 15,
marginBottom: 15,
position: 'absolute',
},
});

It’s important to note that absolute is written as a String and is not written like typical CSS. Another important note is that some of the syntax sugar we get in CSS is nowhere to be found in React Native. Declaring styles in React Native is, well, very declaritive. Since we’re writing JavaScript, we’re not allowed to write statements such as margin: 15 0 as this is just bad syntax. Instead, we break each style into the camel-cased version of the CSS alternative (for the most part.)

StyleSheets are imported into our components and are used by declaring a style attribute on a particular component. We’ll look at an example in a moment.

With the understanding that StyleSheets !== CSS, let’s talk about how we can best format our application to get the most out of our styles.

Reuse Components, Not Styles

When building for the web, we have a countless number of ways to organize our CSS whether that’s using a tool like Sass, Less, PostCSS, etc. This allows us create a hierarchy for our application that makes sense. In the end, we let our tool build all our CSS together to form one cohesive stylesheet for our entire application.

In React Native, we must think of styling in a slightly different manner. Instead of writing one large StyleSheet, we want to continue writing small bite-sized styles. This means that anything and everything that can be reused should be a component. Let’s look at an example:

In a typical web-application, we might write a class to style our buttons.

.button {
background-color: #111;
color: #fff;
padding: 15px;
border-radius: 5px;
}

In React Native, there’s no good way to share styles without writing one large StyleSheet (bad) but we still want to break this styling into it’s own component, say a Button component.

To start, we might want to create two new files, components/Button/index.js and components/Button/styles.js. These files might look like the following:

# components/Button/index.js
import React from 'react';
import {
TouchableHighlight,
Text,
} from 'react-native';
import styles from './styles';
const Button = () => (
<TouchableHighlight style={styles.container}>
<Text style={styles.button}>Click Me</Text>
</TouchableHighlight>
)
export default Button;
# components/Button/styles.js
import { StyleSheet } from 'react-native';
export default StyleSheet.create({
container: {
borderRadius: 5,
},
button: {
backgroundColor: '#111',
color: '#fff',
borderRadius: 5,
padding: 15,
},
});

Now, whenever we want to include a button in our application, we simply import the Button component which will have all necessary styles ready to go.

Let’s talk a moment about container versus button above.

Black Boxes

The TouchableHighlight component in React Native is a special component that gives a user feedback on a tap (click) event they just performed. Without it, the user would tap your button and would receive no feedback (although it would still work.)

TouchableHighlight has some quirks about it especially around transparency. If we didn’t include the borderRadius: 5, we’d have some ugly black boxes around our button whenever we clicked it. You want to ensure that whenever you have a TouchableHighlight, you account for all transparent and non-transparent elements within the component. To rid ourselves of the dreaded black boxes surrounding our button when tapping it, we simply give the TouchableHighlight a matching border radius to ensure there are no transparent pixels to fill in.

Define Common Styles

Chances are you’re not going to have a handful of different styles for colors, font sizes, padding, etc. For styles that are shared amongst many components, it’s a good idea to write a common stylesheet that can be imported into other stylesheets.

An example of a common stylesheet might look like the following:

# styles/common.js
export const COLOR_PRIMARY = '#58C9B9';
export const COLOR_SECONDARY = '#111';
export const FONT_NORMAL = 'OpenSans-Regular';
export const FONT_BOLD = 'OpenSans-Bold';
export const BORDER_RADIUS = 5;

Now when we write out StyleSheets, we can easily use these common styles.

# components/Button/styles.js
import { StyleSheet } from 'react-native';
import { COLOR_PRIMARY, BORDER_RADIUS } from './../styles/common';
export default StyleSheet.create({
container: {
borderRadius: BORDER_RADIUS,
},
button: {
backgroundColor: COLOR_PRIMARY,
borderRadius: BORDER_RADIUS,
},
});

Conclusion

React Native is a fast and easy way to build native applications for the iPhone and Android devices.

By doing some simple planning and organization before you start coding your components will help you tremendously in the long-run by eliminating unnecessary code duplication. A common StyleSheet is useful, especially when a marketing department might want to change the font and colors of the application.

By following these practices, you’ll have a lean and manageable React Native application that any developer can follow.


Originally published at lacke.mn.