Reputation: 589
In React-Native, you can use Stylesheet to create css-like stylesheets. The main reason of using styleshee.create
in favor of plain js-objects is increased performance. However, you often might want to style components dynamically, often based on their props. I basically found three approaches of doing this:
Note for the following examples: Consider const styles ...
to be declared outside of the Component, as it's a common pattern and you might want to share styles between different Components. Consider everything below the tree dots as part of the render function.
Using an array of styles:
const styles = StyleSheet.create({viewStyle: {backgroundColor:'red'}})
...
return <View style={[styles.viewStyle, {color: this.props.color}]} />
Using Stylesheet.flatten:
const styles = StyleSheet.create({viewStyle: {backgroundColor:'red'}})
...
const flattenedStyle = StyleSheet.flatten(styles.viewStyle, {{color: this.props.color}})
return <View style={flattenedStyle} />
Using a function to create the stylesheet:
const styles = (color) => StyleSheet.create({
viewStyle: {
backgroundColor:'red',
color: color
}
})
...
const style = styles(this.props.color).viewStyle
return <View style={style} />
I am wondering which approach is the best regarding to performance, or if there even is another, more performant way? I think Option 2 and 3 are no way to go at all, because dynamically creating new stylesheets on prop-changes undermines the whole purpose of stylesheets. I am happy for any thought or hints on this subject!
Upvotes: 36
Views: 6663
Reputation: 474
One of the approach
// homeSreen
<View style={styles.filterButton(isSelected)}>
<Text> Strawberry </Text>
</View>
// styles.js
import { StyleSheet } from 'react-native';
import { Colors } from '../../theme';
export default StyleSheet.create({
container: {
backgroundColor: Colors.lighter,
},
filterButton: isSelected => ({
padding: 15,
backgroundColor: isSelected? Colors.background.primary: Colors.background.secondary
}),
});
Upvotes: 2
Reputation: 2474
Possibly a bit overkill for simple dynamic styling but Reanimated is very performant and will run the style transition at 60fps https://github.com/software-mansion/react-native-reanimated
It archives this by declaring all the styles needed for an animation/transition ahead of time and runs them on the native thread so there is minimal communication across the JS->Native code bridge.
There is a better explanation on their about page here https://docs.swmansion.com/react-native-reanimated/docs/about
Upvotes: -1
Reputation: 1270
Here you can do dynamic styling in react native for each styling.
Like this
<Text style={styles.simpleText('red')}>Required field</Text>
// In styling
const styles = StyleSheet.create({
simpleText: (colorProp = 'black') => ({ // default black set
fontSize: 14,
color: colorProp,
})
})
and you can also pass any data type for conditional styling
Upvotes: 5
Reputation: 1850
Did you consider CSS in JS libraries like Styled components
?
You can pass props and get dynamic style regard that:
https://styled-components.com/docs/basics#passed-props
Upvotes: 0
Reputation: 2944
You could memoize stylesheet creation using React hooks, but first you need to do some performance checking in order to determine if stylesheet creation is in fact a CPU and/or memory hog worth optimizing.
Here's an example:
const styles = (color) => StyleSheet.create({
viewStyle: {
backgroundColor:'red',
color: color
}
})
/*
even though makeStyle is defined in EVERY render,
React will only run it ONCE for any given props.color distinct value.
The resulting value `styles` survives re-renders
*/
const makeStyle = () => styles(props.color)
const styles = useMemo(makeStyle, [props.color]);
And here's the official documentation.
Upvotes: 0