107
votes

I'm new with React and I understand the benefits of the component based, inline styles. But I'm wondering if there is a decent way to have some sort of global style. For instance, I'd like to use the same Text and Button coloring throughout my app.

Rather than repeat in every component(and subsequently have to change it in x places if need be), my initial thought is to create a 'base' StyleSheet class in it own file and import it in my components.

Is there a better or more 'React' way?

11

11 Answers

127
votes

You may create a reusable stylesheet. Example:

style.js

'use strict';
import { StyleSheet } from 'react-native';

module.exports = StyleSheet.create({
    alwaysred: {
        backgroundColor: 'red',
        height: 100,
        width: 100,
    },
});

In your component:

const s = require('./style');

...then:

<View style={s.alwaysred} ></View>
92
votes

Create a file for your styles (I.E., Style.js).

Here is an example:

import { StyleSheet } from 'react-native';

export default StyleSheet.create({
  container: {
    flex: 1
  },
  welcome: {
    fontSize: 20
  }
});

In any of the files you want to use your style, add the following:

import styles from './Style'
11
votes

If you just wanted to set some global variables you could try.

AppStyles.js

export default AppStyles = {
    colour: {
        background: '#f4f9fd',
        font: '#434e5a',
        primary: '#ff3b30'
    }
}

index.ios.js

import AppStyles from './AppStyles';

const styles = StyleSheet.create({
    container: {
        backgroundColor: AppStyles.colour.background
    }
});
10
votes

You may also try react-native-extended-stylesheet that supports global styling variables:

// app.js
EStyleSheet.build({
   buttonColor: 'green'
});

// component.js
var styles = EStyleSheet.create({
  button: {
    backgroundColor: '$buttonColor',
    ...
  }
});
8
votes

You must create a file to store all style in it like 'styles.js' and write the css type code as you need

'use strict';
import {StyleSheet} from 'react-native';

export default StyleSheet.create({

    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },

    title: {
        fontSize: 10,
        color: '#000',
        backgroundColor: '#fff'
    },

    button: {
        fontSize: 12,
        color: '#000',
        backgroundColor: '#fff'
    }

});

and now you can use the global style as you can see

import React, { Component } from 'react';
import { View, Button } from 'react-native';
import StyleSheet from './config/styles';

export default class App extends Component {

  render() {
    return (
      <View
        style={StyleSheet.container}>
        <Button
          style={StyleSheet.button}
          title="Go to Lucy's profile"
        />
      </View>
    );
  }
}
2
votes

Try my library react-native-style-tachyons, which not only gives you global styles, but a design-first, responsive layouting system with widths and heights relative to your root fontsize.

1
votes

All these methods directly answer the question but as far as I'm concerned, it's not the way to do it in a component based design system like React.

We can start with atomic components, then layer and group them all the way to the top. The following article might make this train of thought more clear: http://atomicdesign.bradfrost.com/chapter-2/

In the natural world, atomic elements combine together to form molecules. These molecules can combine further to form relatively complex organisms.

If you need a base component that does not exist, you make it. Then you can make other, less specific components with it. for instance:

// rerender is cheaper without style prop when
// the default style is an unchanged reference
// instead of a new object every time.
const style = {
  color   : 'MidnightBlue',
  fontSize: 14,
}

function getStyle (styleProp) {
  // styleProp is able to overwrite style
  if (styleProp) return {...style, ...styleProp}
  else return style
}

export default function CustomText (props) {
  return (
    <Text style={getStyle(props.style)}>
      {props.children}
    </Text>
  )
}

Then use CustomText everywhere instead of Text. You can also do it with View, div, span or anything else.

0
votes

External CSS file main.css

'use strict';

var {
   StyleSheet,
 } = 'react-native';

module.exports = StyleSheet.create({

  main: {
     backgroundColor: 'gray',
     height: 20,
     width: 100,
  }
});

create instance of css file in component.

var mainCss = require('./main');

<View style={mainCss.main}><Text>Hello</Text></View>
0
votes

Here you can find a elegant way to sort your styles and then import into the different components, you can create a folder in which you gather all the styles files and create and index.js which is going to work as facade:

the index.js will look like:

import Variables from './variables';
import GlobalStyles from './global'; 

export { Variables, GlobalStyles };

and then import like this:

import { GlobalStyles } from './stylesheets/index';

Here for further information:

https://thoughtbot.com/blog/structure-for-styling-in-react-native

0
votes

I got mine working using similar

Create a directory called 'constants' Create a file in ./constants/AppStyles.js

 /**
 * Project level stylesheet for common styles
 */


import { StyleSheet } from 'react-native';

export default StyleSheet.create({
  container: {
    flex: 1,
    margin: 20,
    alignItems: 'center',
    alignContent: 'center',
    paddingVertical: 60
  }
  
});

Then in App.js reference this file and the styles created.

import React from 'react';
import {
  View,
  Text
} from 'react-native';
import AppStyles from './constants/AppStyles';

const App = () => {
  return (
    <View style={ AppStyles.container }>
      <Text>MOST BASIC Template EVER!</Text>
    </View>
  );
};

export default App;

Traps I fell into

  • I had curly braces around import {AppStyles} from './constants/AppStyles'; WRONG :-(
  • I created AppStyles as a component and tried exporting a const WRONG :-)

Found a good course online and figured it out from there

-4
votes

Take a look at Shoutem Themes for React Native.

Here is what you get with Shoutem Theme:

Global style where certain style is automatically applied to component by its style name:

const theme = {
  'my.app.ComponentStyleName': {
    backgroundColor: 'navy',
  },
};

Activating certain component specific style with styleName (like CSS class):

const theme = {
  'my.app.ComponentStyleName': {
    '.rounded': {
      borderRadius: 20,
    },
    backgroundColor: 'navy',
  },
};

// Implementation - will apply borderRadius to Component
<Component styleName="rounded"/>

Automatic style inheritance:

const theme = {
  'my.app.ComponentStyleName': {
    'my.app.ChildComponentStyleName': {
      backgroundColor: 'red',
    },
    '.rounded': {
      borderRadius: 20,
    },
    backgroundColor: 'navy',
  },
};

// Implementation - will apply red background color to ChildComponent
<Component styleName="rounded">
  <ChildComponent/>
</Component>

Nested style for composed components:

const theme = {
  'my.app.ComponentStyleName': {
    containerView: {
      paddingTop: 10,
    },
    innerView: {
      backgroundColor: 'yellow',
    },
  },
};

// Of course do not forget to connect Component
function Component({ style }) {
  return (
   <View style={style.containerView}>
    <View style={style.innerView}>
     <Text>Warning with yellow background.</Text>
    </View>
   </View>
  );
}

To get it work you need to use StyleProvider, the wrapper component which provides style to all other component through context. Similar to Redux StoreProvider.

Also you need to connect your component to style with connectStyle so you always use connected component. Similar to Redux connect.

export const styledComponent = connectStyle('my.app.ComponentStyleName',
                                { ...defaultStyleIfAny })(Component);

You can see example within documentation.

One last thing, we have also provided set of components in our UI ToolKit which are already connected to style, so you can just import them and style in your global style/theme.