Passing props into external stylesheet in React Native?
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
}})
Related videos on Youtube
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, 2022Comments
-
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:
index.js
for all the React code, and;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 about 7 yearsThat 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 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ć over 3 yearsThis does seem to work but typescript will complain.
-
Syed Amir Ali over 3 years@DomagojVuković no idea for typescript
-
CatalinBerta about 3 yearsTBH, 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 almost 3 yearsAre there any performance drawbacks by using this method because this will initiate an arrow function ?
-
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 over 2 yearsbetter put all dynamic styles into one function, generate static then render, otherwise it gets called too many times
-
Samiksha Jagtap about 2 yearswhy to create class field when it can directly pass to stylesheet
-
JCraine about 2 yearsIt's better for performance to use:
style={[styles.tabItem_bottomView, { backgroundColor: selected ? Color.blue : Color.white ]}
-
Shoaib Mirza about 2 yearsWhy? Can you explain a bit?
-
JCraine about 2 yearsI 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 about 2 yearsNo worries, Thank you for the info. I'll see if i can find anything regarding this
-
JCraine about 2 yearsCheers, likewise if I come across the doc again I'll post here it.
-
Uzef Shaikh almost 2 yearswhy one would like to prefer classes in the era of functional component