Search code examples
react-nativestyled-components

Cascade text color with Styled Components on React Native


I'm trying to create a component with React Native that includes a <Text> component inside the wrapped component:

const MyComponent = props => (
  <View {...props}>
   <Text {...props}>Hello world</Text>
  <View>
)

const MyRedComponent = styled(MyComponent)`
  color: #000;
  margin-left: 10px;
  background: #F00;
`

I'm composing my component this way so I could change the the text color from the same styled component as I'm changing the background color:

const MyBlueComponent = styled(MyRedComponent)`
  color: #FFF;
  background: #00F;
`

However with this approach there is a problem that all of the styles get applied to the <Text> component, not only the color; in this example the <Text> component also gets the margin-left style from the parent styles which is not preferred. I'd only like the text color to be cascaded to the <Text> component.

Is this possible using Styled Components with React Native?


Solution

  • You can create a wrapper function using StyleSheet.flatten and pick the color from the resulting object:

    const MyComponent = props => (
      <View {...props}>
        <Text style={{ color: StyleSheet.flatten(props.styles).color }}>Hello world</Text>
      <View>
    )
    
    const MyRedComponent = styled(MyComponent)`
      color: #000;
      margin-left: 10px;
      background: #F00;
    `
    

    It makes sense to extract the picking to its own function. For example you could create the following wrapper:

    const pickColorFromStyles = styles => {
      const { color } = StyleSheet.flatten(styles)
      return { color }
    }
    

    ...and use that function in your component:

    const MyComponent = props => (
      <View {...props}>
        <Text style={pickColorFromStyles(props.styles)}>Hello world</Text>
      <View>
    )
    

    Notice the warning with using StyleSheet.flatten from the documentation page:

    NOTE: Exercise caution as abusing this can tax you in terms of optimizations. IDs enable optimizations through the bridge and memory in general. Refering to style objects directly will deprive you of these optimizations.