Passing props into external stylesheet in React Native?

34,765

Solution 1

Create a class that takes iconColor and iconSize as arguments and returns a StyleSheet object

// styles.js

export default class StyleSheetFactory {
    static getSheet(iconSize, iconColor) {
        return StyleSheet.create({
            icon : {
                color: iconColor,
                fontSize: iconSize
            }
        })
    }
}

// index.js

render() {
    let myStyleSheet = StyleSheetFactory.getSheet(64, 'red')
}

Solution 2

I rather to have my styles in a separate file styles.js. Inside styles.js:

export const styles = (props) => StyleSheet.create({
        icon : {
        color: props.iconColor,
        fontSize: props.iconSize
      }
    }

Inside your main class you can pass the value

return (
    <Icon style={styles(this.props).icon} />
  );

Alternatively you can those value directly so it would be

export const styles = (iconColor,iconSize) => StyleSheet.create({
    icon : {
    color: iconColor,
    fontSize: iconSize
  }
}

and inside your main class

return (
    <Icon style={styles(this.props,iconColor, 
this.props.iconSize).icon} />
 );

Solution 3

i'm sending noFooter boolean prop in a style sheet

   <View style={styles.mainFooterCont(noFooter)}>
     <Text> Testing </Text>
    </View>

and receiving it like

  mainFooterCont: noFooter => ({
   flexDirection: 'row',
   justifyContent: 'space-between',
   alignItems: 'flex-end',
   paddingBottom: noFooter ? 0 : 20,
   paddingTop: Metrics.ratio(noFooter ? 0 : 5),
   }),

Solution 4

Just wrap stylesheet in a function where you can optionally pass props.

Instead of:

const styles = StyleSheet.create({
  Title: { color: 'white' }
});

You do:

const styles = (props?: any) => StyleSheet.create({
  Title: { color: 'white' }
});

And now when you add them to your components, instead of

style={styles.Title}

You do:

style={styles(propsObjectHere).Title}

and since this is optional and you have no props to pass, just do:

style={styles().Title}

P.S. ignore the type if you, for some reason, are not using TypeScript :P

Solution 5

Solution:

render() {

   const iconColor = this.props.color || '#000';
   const iconSize = this.props.size || 25;

   return (
   <Icon style={{...styles.icon, color: iconColor, fontSize: iconSize }} />

Example styles.js:

  const styles = StyleSheet.create({
  icon : {
    color: iconColor,
    fontSize: iconSize
  }})
Share:
34,765

Related videos on Youtube

chapeljuice
Author by

chapeljuice

Job: Lead UI developer at RedAwning, mostly focusing on app development. I actually like CSS! Life: 2 awesome kids, an amazing wife, a dog, and a tortoise. We love the PNW!

Updated on February 09, 2022

Comments

  • chapeljuice
    chapeljuice about 2 years

    I'm new to React and React Native. At the moment for each component I'm breaking the code into 2 separate files:

    1. index.js for all the React code, and;
    2. styles.js for the StyleSheet

    Is there a way to pass props into the external StyleSheet?

    Example: index.js:

    render() {
      const iconColor = this.props.color || '#000';
      const iconSize = this.props.size || 25;
    
      return (
        <Icon style={styles.icon} />
      );
    }

    Example styles.js:

    const styles = StyleSheet.create({
      icon : {
        color: iconColor,
        fontSize: iconSize
      }
    });

    The code above does not work, but it's more there just to get the point across of what I'm trying to do. Any help is much appreciated!

  • chapeljuice
    chapeljuice about 7 years
    That does indeed work, so thank you. I replaced the static parameters you're passing in with the props to make it more dynamic. However, I'm not certain it's the most elegant solution. What if I have more than 2? I'm also not 100% certain splitting up the styles and the react code is the best, I'm just trying to learn as much as I can. Thanks again!
  • FuzzyTree
    FuzzyTree about 7 years
    @chapeljuice I personally prefer not splitting up styles because I find it makes the code more readable and prefer making additional components with inline styles vs having a huge style sheet where I have to lookup a style - in the end it comes down to preference but there are benefits to having separate sheets see stackoverflow.com/questions/39336266/… -
  • Domagoj Vuković
    Domagoj Vuković over 3 years
    This does seem to work but typescript will complain.
  • Syed Amir Ali
    Syed Amir Ali over 3 years
    @DomagojVuković no idea for typescript
  • CatalinBerta
    CatalinBerta about 3 years
    TBH, reflecting on this after using it, I find it quite messy and creates unnecessary dependencies in your style. What I ended up doing is create static styles and just conditionally change styles at component level through the styles attribute. <Component style={ StyleSheet.flatten([MainStyle, props.darkMode ? {color: '#333'} : {}]) } /> <== untested code
  • John Stuart
    John Stuart almost 3 years
    Are there any performance drawbacks by using this method because this will initiate an arrow function ?
  • ICW
    ICW over 2 years
    @JohnStuart The "Performance drawback" is the exact same a typical inline style: A new style object will be created every time the component renders, since stylesheet.create is being called every time the component renders. In practice is it very unlikely that it will matter even a little bit, though.
  • MartianMartian
    MartianMartian over 2 years
    better put all dynamic styles into one function, generate static then render, otherwise it gets called too many times
  • Samiksha Jagtap
    Samiksha Jagtap about 2 years
    why to create class field when it can directly pass to stylesheet
  • JCraine
    JCraine about 2 years
    It's better for performance to use: style={[styles.tabItem_bottomView, { backgroundColor: selected ? Color.blue : Color.white ]}
  • Shoaib Mirza
    Shoaib Mirza about 2 years
    Why? Can you explain a bit?
  • JCraine
    JCraine about 2 years
    I can't remember where I read it now, but there was some doc somewhere that mentioned favouring style arrays to object spreading. I think spreading is slightly costlier on re-renders, but take it with a grain of salt because I can't remember the source, sorry!
  • Shoaib Mirza
    Shoaib Mirza about 2 years
    No worries, Thank you for the info. I'll see if i can find anything regarding this
  • JCraine
    JCraine about 2 years
    Cheers, likewise if I come across the doc again I'll post here it.
  • Uzef Shaikh
    Uzef Shaikh almost 2 years
    why one would like to prefer classes in the era of functional component