Christoph Göttert
Christoph Göttert

Reputation: 589

What is the most performant way for dynamic styling in React-Native?

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.

  1. Using an array of styles:

    const styles = StyleSheet.create({viewStyle: {backgroundColor:'red'}})
    ...
    return <View style={[styles.viewStyle, {color: this.props.color}]} />
    
  2. Using Stylesheet.flatten:

    const styles = StyleSheet.create({viewStyle: {backgroundColor:'red'}})
    ...
    const flattenedStyle = StyleSheet.flatten(styles.viewStyle, {{color: this.props.color}})
    return <View style={flattenedStyle} />
    

  3. 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

Answers (5)

Utonium
Utonium

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

Jack Vial
Jack Vial

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

Zuhair Naqi
Zuhair Naqi

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

Belal mazlom
Belal mazlom

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

Tudor Ilisoi
Tudor Ilisoi

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

Related Questions