react-nativereact-native-stylesheetreact-native-component

How to apply values from props to styles?


I created a custom component:

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

const Square = ({size, color, onPress, children}) => {
  return (
    <TouchableOpacity onPress={onPress}>
      <View style={styles.sqr}>{children}</View>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  sqr: {
    width: this.size,
    height: this.size,
    backgroundColor: this.color,
    ...
  },
});

export default Square;

As you can see above in the sqr style, I try to use the size and color passed in via props.

I use the Square in another component in following way:

<Square size={30} color="black" .../>

However the size and color are not applied when run my app.

So, how can I use passed in values in styles of custom component?


Solution

  • There are a few ways of handling conditional styles within your react-native components. In your example, you only have access to size and color within the Square component itself, not the object created by Stylesheet.create. In this case, it's common to pass a list of objects to your style attribute where you have access to those values:

    const Square = ({size, color, onPress, children}) => {
      return (
        <TouchableOpacity onPress={onPress}>
          <View
            style={[styles.sqr, { height: size, width: size, color: color }]}
          >
            {children}
          </View>
        </TouchableOpacity>
      );
    };
    

    Since the style attribute accepts a list of objects, you can also take this quite a bit further to provide 'active' classes based on props passed to your component. Here's a more complex example if you needed to pass in a style object from a parent and potentially toggle on/off some hypothetical 'active' style:

    const Square = ({size, color, onPress, otherStyles, active, children}) => {
      return (
        <TouchableOpacity onPress={onPress}>
          <View
            style={[
              styles.sqr,
              otherStyles,
              { height: size, width: size, color },
              active ? styles.active : null,
            ]}
          >
            {children}
          </View>
        </TouchableOpacity>
      );
    };
    
    const styles = StyleSheet.create({
      active: {
        backgroundColor: 'red',
      },
    });