Search code examples
react-nativestylesheet

ReactNative inline style vs Stylesheet.create


I ran into a problem today. I wanna make sure my app looks good and that requires me to do a lot of tuning especially in margin/padding part.

My question is: Which approach better? Create multiple stylesheets (on the parent component) just to accommodate these little changes (i'm using reusable components with margin-less stylesheets, those margins will be inherited from parent component) OR just let it be inlined on the component?

I know that creating stylesheet would likely be the better approach. But then to accommodate that inherited styles, I will use style={[myComponentStyle, passedDownParentStyle]} <- doesn't it will create a new stylesheet nevertheless and by then nullify the purpose of using Stylesheet.create in the first place?

Could anyone expert on this give me some insight?

EDIT Example:

const Style = Stylesheet.create({
 child: {
  color: 'red'
 },
 parent1: {
  padding: 5,
  margin: 10
 },
 parent2: {
  padding: 10,
  margin: 5
 }
})

class Child {
 render() {
  return (
   <Text style={[Style.child, this.props.style]}>
    {this.props.children}
   </Text>
  )
 }
}

class Parent1 {
 render() {
  return (
   <Child style={Style.parent1}>
    Hello
   </Child>
  )
 }
}

class Parent2 {
 render() {
  return (
   <Child style={Style.parent2}>
    World
   </Child>
  )
 }
}

UPDATE My question is: Isn't the usage of style={[Style.child, this.props.style]} nullify the purpose of Stylesheet.create? Shouldn't I just not use it at all instead?


Solution

  • From the React Native docs:

    Code quality:

    • By moving styles away from the render function, you're making the code easier to understand.
    • Naming the styles is a good way to add meaning to the low level components in the render function.

    Performance:

    • Making a stylesheet from a style object makes it possible to refer to it by ID instead of creating a new style object every time.
    • It also allows to send the style only once through the bridge. All subsequent uses are going to refer an id (not implemented yet).

    So that's my understanding of why creating a Stylesheet is a better approach.

    Now to answer your question:

    I think you could pass down a map of styles, combine that with a map of your component styles, and create a stylesheet from the combination of the two. Alternatively, you could treat any passed down styles as an override to the default component styles and just make each of those a Stylesheet instead (since it would only use one or the other). If the child is supposed to wrapped by the parent component, however, you may not have to do any of this at all as the styles may be inherited already. (Edit: This is wrong, so ignore this part)

    If you could provide more context with some additional code, I may be able to provide greater insight.

    Update:

    You could also use StyleSheet.flatten (see here). However, it comes with the following warning:

    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.

    Like I said earlier, you'd probably want to pass down the map instead first as a prop and then do Stylesheet.create on the flattened map (i.e., the combined map of the prop one and the default for the component).