styles in react native

Super Simple Guide for Organizing Styles in React Native (6 Steps)

The nice thing about organizing styles in React Native is that everything is JavaScript. React Native uses a JavaScript class called StyleSheet that resembles normal CSS in many ways, but there are some key differences:

  • camelCase instead of kebab-case for style properties
  • make use of JavaScript constants and functions to organize and calculate our styles
  • style property values in StyleSheets need to be strings or numbers (but you can still use js constants and/or functions to declare them)
  • instead of pixels, React Native uses “units” that get converted into pixels
  • no shortcuts for padding or margin, (i.e. need to explicitly set paddingTop and paddingRight). – Note that you can use paddingVertical/paddingHorizontal
  • no media queries, instead just use Flexbox (click here for a deep dive into on Flexbox in React Native)

In many React Native projects, sometimes organizing styles in react native have the tendency to get messy very quickly. That’s because in React Native, every component accepts a “style” prop where these are defined. In my experience, this encourages developers to define styles within individual component files, or worse, to write inline styles on the components themselves.

Defining styles and writing inline styles will inevitably lead to a variety of issues around maintenance, consistency, and organization.

Organizing React Native styles

We should completely refrain from writing styles in our components. So, where to define our styles if not in the component itself? A nice approach is to create a folder for each component or set of components.

In our component’s subdirectory, we can add a file called style.js. In here, create the component-specific stylesheet which we will ultimately import into our component file. With this approach, we’ll have successfully abstracted our styles out of our component code. Awesome!

While that’s a huge improvement from styles being defined inside our components, we can still do better while organizing styles in React Native. With the above approach, we are able to create styled components that can easily be reused and maintained. However, there will likely be a lot of unnecessarily repeated styles throughout our various components’ stylesheets.

This causes obvious problems with maintainability, since if one recurring style changes, it will need to be updated everywhere as opposed to one place.

Creating a simple base stylesheet

Solve maintainability challenges by breaking generic base styles out into a higher level module that can be used when we create specific component stylesheets. Here is an example of a simple base stylesheet that we can use to create component-specific stylesheets:

// app/styles/base.js

import {StyleSheet, Dimensions} from 'react-native'

export const dimensions = {
  fullHeight: Dimensions.get('window').height,
  fullWidth: Dimensions.get('window').width
}
  
export const colors  = {
  primary: '#226B74',
  secondary: '#254B5A',
  tertiary: '#5DA6A7'
}

export const padding = {
  sm: 10,
  md: 20,
  lg: 30,
  xl: 40
}

export const fonts = {
  sm: 12,
  md: 18,
  lg: 28,
  primary: 'Cochin'
}

We can now import our base styles above into our component specific stylesheets:

Our component’s stylesheet:

// app/components/panel/style.js

import {colors, fonts, padding, dimensions} from '../../styles/base.js'

export default const panelStyles = StyleSheet.create({
  container: {
    paddingHorizontal: padding.sm,
    paddingVertical: padding.lg,
    width: dimensions.fullWidth
  },
  header: {
    fontSize: fonts.lg,
    fontFamily: fonts.primary
  },
  section: {
    paddingVertical: padding.lg,
    paddingHorizontal: padding.xl
  }
})

Our component:

// app/components/panel/index.js

import styles from './style.js'

export default class Panel extends Component {
 render() {
   return (
     <View style={styles.container}>
       <Text style={styles.header}>Basic Header</Text>
       <Text style={styles.section}>Basic Section Text</Text>
     </View>
   )
 }

Let’s go a step further by improving our base styles that we are importing into our component stylesheets. Add the following code to your base stylesheet:

Our base styles module:

// app/styles/base.js
…

// added below our colors, fonts, padding etc
// base styles
const baseStyles = {
  container: {
    paddingHorizontal: padding.sm,
    paddingVertical: padding.lg,
    width: dimensions.fullWidth
  },
  header: {
    backgroundColor: 'transparent',
    fontSize: fonts.lg,
    fontFamily: fonts.primary,
    fontWeight: 'bold'
  },
  section: {
    paddingVertical: padding.lg,
    paddingHorizontal: padding.xl
  },
}

export default function createStyles(overrides = {}) {
  return StyleSheet.create({...baseStyles, ...overrides})
}

So, now our base styles module is exporting a createStyle function by default. This function acts essentially the same as StyleSheet.create, except that it also accepts optional style overrides. We could use it at its simplest inside our component like so:

Our component:

// app/components/panel/index.js

import createStyles from '../../styles/base.js'

// creates our default base stylesheet (no overrides)
const styles = createStyles()

export default class Panel extends Component {
 render() {
   return (
     <View style={styles.container}>
       <Text style={styles.header}>Basic Header</Text>
       <Text style={styles.section}>Basic Section Text</Text>
     </View>
   )
 }

Let’s say we want to override some specific styles on this component. We want the section to have medium sized font with secondary text color. All we need to do is add some overrides to our createStyles function within our component stylesheet:

Our component stylesheet:

// app/components/panel/style.js

import createStyles, {fonts, colors} from '../../styles/base.js' 

export default const panelStyles = createStyles({
  section: {
    fontSize: fonts.md,
    color: colors.secondary
  }
})

Our component:

// app/components/panel/index.js

import style from './style.js'

export default class Panel extends Component {
 render() {
   return (
     <View style={styles.container}>
       <Text style={styles.header}>Basic Header</Text>
       <Text style={styles.section}>Basic Section Text</Text>
     </View>
   )
 }

This implementation affords us a couple of good practices while organizing styles in React Native.

  • We have base styles that will be used throughout our component-specific styles, making everything easier to maintain and update in the future.
  • Component-specific styles are located right next to the component JavaScript file, so they are easy to find.
  • We’ve avoided the unsightly inline styles in our components which makes them hard to read.

There you have it: a useful overview of how to organize styles in React Native. Let us know if you implement these processes, or suggest an update!

React Resources

Check out the official React page for upcoming React conferences!

Here are other articles around the web about React Native styles:

This post was originally published on December 27, 2017

For more from Revelry on organizing styles in React Native, check out some of these posts:

https://revelry.co/ux-design-react-native/
https://revelry.co/react-native-setting/
https://revelry.co/numerical-keypad-react-native/

At Revelry, we are building products people love to use.

Apply to work with us  or hire our engineers to round out your tech team!

Check out more of our thoughts on development and product.

We're building an AI-powered Product Operations Cloud, leveraging AI in almost every aspect of the software delivery lifecycle. Want to test drive it with us? Join the ProdOps party at ProdOps.ai.