Merge / Combine two or more different StyleSheet components in React Native?

23,685

Solution 1

you are very close:

const baseStyles = [baseStyle, platformStyle];

basically any component can cascade styles like this:

<View style={[styles.style1,styles.style2]}></View>

Solution 2

You can also use StyleSheet.flatten method. See documentation here.

var styles = StyleSheet.create({
  listItem: {
    flex: 1,
    fontSize: 16,
    color: 'white',
  },
  selectedListItem: {
    color: 'green',
  },
});

StyleSheet.flatten([styles.listItem, styles.selectedListItem]);
// returns { flex: 1, fontSize: 16, color: 'green' }

UPDATE:

StyleSheet.flatten internally uses StyleSheetRegistry.getStyleByID(style) to resolve style objects represented by IDs. IDs enable optimizations through the bridge and memory in general. Referring to style objects directly will deprive you of these optimizations.

So flatten method is better than style={ [ styles.listItem, styles.selectedListItem ] }

Solution 3

You can combine style sheets using the spread operator '...', be warned that any variables of the same name will be overwritten by the last instance.

Heres a small demo app to demonstrate:

'use strict';
import React, { Component } from 'react';
import {
   Alert,
   Button,
   StyleSheet,
   Text,
   AppRegistry,
   View,
 } from 'react-native';

class listTest extends Component {

render() {
  return (

   <View style={styles3.myViewBox}>
      <Text style = {styles3.myTextBox1}>
        TEST
      </Text>
    </View>
   );
  }
 }

const styles = StyleSheet.create({
  myTextBox1: {
     backgroundColor:'red',
  },
  myViewBox: {
    backgroundColor:'blue',
    margin:15,
    padding:15,
  }

});

const styles2 = StyleSheet.create({
  myTextBox2: {
    backgroundColor:'yellow',
  },
  myViewBox: {
    backgroundColor:'green',
    margin:15,
    padding:15,
  },
});

const styles3 = {...styles,...styles2};

AppRegistry.registerComponent('listTest', () => listTest);

EDIT:

If you're running ES5 you can just use:

const styles3 = Object.assign(styles,styles2);

Solution 4

Now ReactNative lets you combine two styles using a more functional approach. Use the function StyleSheet.compose so you can do the following as per documentation:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

const App = () => (
  <View style={container}>
    <Text style={text}>React Native</Text>
  </View>
);

const page = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
    backgroundColor: '#fff',
  },
  text: {
    fontSize: 30,
    color: '#000'
  },
});

const lists = StyleSheet.create({
  listContainer: {
    flex: 1,
    backgroundColor: '#61dafb',
  },
  listItem: {
    fontStyle: 'italic',
    fontWeight: 'bold'
  },
});

const container = StyleSheet.compose(page.container, lists.listContainer); // if you wanna compose more than one style just use a map.reduce function and compose two at the time until you have consumed you list of styles
const text = StyleSheet.compose(page.text, lists.listItem);

export default App;
Share:
23,685
R01010010
Author by

R01010010

I'm trying to improve the web application world.

Updated on March 25, 2021

Comments

  • R01010010
    R01010010 about 3 years

    I'm separating my styles in the following way:

    styles /
    |-- base.js
    |-- base.ios.js
    |-- base.android.js
    

    Each of them exports a StyleSheet component created as in this example:

    import { StyleSheet } from 'react-native';
    
    export default StyleSheet.create({
        statusBar: {
        height: 20
    });
    

    How can I merge them so I only have one base style object? I'm looking for something like:

    const baseStyles = mergeStyles(baseStyle, platformStyle);