How to inherit style within StyleSheet.create in React Native (using destructuring syntax maybe)
Asked Answered
P

4

6

I want to reuse styles within StyleSheet.create's parameter object, how to do that?

See the code:

const styles = StyleSheet.create({
  style1: {
    color: "red",
    backgroundColor: "white"
  },
  style2: {
    width: 100,
    ...style1
  }
})

Originally, I want style2 to inherit all color and backgroundColor from style1, and expand 1 more property called width. So I did try the code above, but then it got an error "style1 is not declared". I realized the problem, so I replaced ...style1 with ...this.style1, the error went away, but it didn't work as I expected. I wondered why and tried running this snippet in javascript to test the behavior:

styles = {
  style1: {
    color: "red",
    backgroundColor: "white"
  },
  style2: {
    width: 100,
    inherit: this.style1
  }
}
console.log(styles.style2.inherit)

It pooped out the result undefined, which is not styles.style1. I realized the problem again and after replacing inherit: this.style1 with inherit: styles.style1, the javascript snippet works, but not in the React Native code.

I think until now, you understand what I want, so my question is how could I achieve that (reuse style code in React Native)? I think there would be many workarounds, so please give me as many as you can. Thank you.

Here is the list of syntaxes I did try but not get the expected result (or as my brain is not working well, I was wrong):

...style1
...this.style1
...styles.style1
...StyleSheet.style1
...StyleSheet.flatten(styles.style1)
Preprandial answered 2/10, 2019 at 7:47 Comment(1)
I'm pretty new to React Native so if there's something wrong with my question, pardon me.Preprandial
P
0

Years after I posted the question I and realized that self-referencing is actually possible with getter

styles = {
  style1: {
    color: "red",
    backgroundColor: "white"
  },
  get style2() {
    return {
      ...this.style1,
      width: 100,
    }
  }
}
console.log('style1', styles.style1)
console.log('style2', styles.style2)
Preprandial answered 5/4 at 12:16 Comment(0)
D
9

It's impossible to Self-references in object literals / initializers

Solution: 1

const baseStyle = {
  color: 'red',
  backgroundColor: 'white'
}

const styles = StyleSheet.create({
  style1: baseStyle,
  style2: {
    width: 100,
    ...baseStyle
  }
})

Solution 2 Use Styled Components to manage and reuse styles easily.

Dorise answered 2/10, 2019 at 8:1 Comment(1)
I'll take a look at Styled Components later. Thank you very much.Preprandial
P
0

I know 1 workaround is to put the "reuseable" style1 object outside of StyleSheet.create:

const style1 = {
  color: "red",
  backgroundColor: "white"
}
const styles = StyleSheet.create({
  style2: {
    width: 100,
    ...style1
  }
})

Is there a better way? Because style1 can also be a style used by another element, I can't use <Element style={styles.style1}/> any more...

Preprandial answered 2/10, 2019 at 7:52 Comment(0)
S
0

a better way to reuse and compose stylesheet:

const baseStyles = StyleSheet.create({
  container: {
    borderWidth: 1,
    borderRadius: 10,
    flex: 1,
  },
});

export const styles = StyleSheet.create({
  container: baseStyles.container,
  card: {
    backgroundColor: "lightblue",
    ...baseStyles.container,
  },
});
Spank answered 4/3 at 9:2 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Unequivocal
P
0

Years after I posted the question I and realized that self-referencing is actually possible with getter

styles = {
  style1: {
    color: "red",
    backgroundColor: "white"
  },
  get style2() {
    return {
      ...this.style1,
      width: 100,
    }
  }
}
console.log('style1', styles.style1)
console.log('style2', styles.style2)
Preprandial answered 5/4 at 12:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.