React Native global styles

React Native

React Native Problem Overview


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?

React Native Solutions


Solution 1 - React Native

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>

Solution 2 - React Native

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'

Solution 3 - React Native

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
    }
});

Solution 4 - React Native

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',
    ...
  }
});

Solution 5 - React Native

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>
    );
  }
}

Solution 6 - React Native

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.

Solution 7 - React Native

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

Solution 8 - React Native

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.

Solution 9 - React Native

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>

Solution 10 - React Native

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

Solution 11 - React Native

A better solution would be to use global object and create a separate theme file.

Import that file inside the root file.

import theme from './theme'
global.theme = theme

Then any component in anywhere in the project can use it as follows

<Text style={global.theme.text} > Stackoverflow Answer </Text>

This way, we don't have to import the main style file again and again. The theme can be managed through one file

Solution 12 - React Native

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPatmView Question on Stackoverflow
Solution 1 - React NativeboredgamesView Answer on Stackoverflow
Solution 2 - React NativeBarlow TuckerView Answer on Stackoverflow
Solution 3 - React NativeRobView Answer on Stackoverflow
Solution 4 - React NativevitaletsView Answer on Stackoverflow
Solution 5 - React NativeAmintabarView Answer on Stackoverflow
Solution 6 - React NativeFabian ZeindlView Answer on Stackoverflow
Solution 7 - React NativepebpcnmView Answer on Stackoverflow
Solution 8 - React NativeThaJayView Answer on Stackoverflow
Solution 9 - React Nativeharpreet cheemaView Answer on Stackoverflow
Solution 10 - React NativeJose RojasView Answer on Stackoverflow
Solution 11 - React NativeAli AbbasView Answer on Stackoverflow
Solution 12 - React NativeMr BrView Answer on Stackoverflow