React-Native-Web Creates Automatic Classes for in-line Style and Applies Them in the Wrong Order

Viewed 32

This is a react native web and a NextJS project.

I use inline styles in React, and it seems like RN-Web is messing those up. There's some code under the hood that combines commonly used styles into automatic classes and applies them when the code is compiled. For example:

.r-borderWidth-rs99b7 {
    border-width: 1px;
}

This is fine, I assume it's some kind of micro optimization built into the framework. The problem is it's applying them in the wrong order (and also duplicating one which may be the problem).

Here is my source code:

<TouchableOpacity
            style={{
              width: '100%',
              padding: 8,
              borderRadius: 32,
              borderColor: '#aaa',
              flexDirection: 'row',
              alignItems: 'center',
              borderWidth: 1,
            }}
            onPress={() => console.log('pressed')}
          >
...
</TouchableOpacity>

But when it compiles into HTML from NextJS I end up with:

element.style {
    align-items: center;
    border-color: rgb(170, 170, 170);
    border-radius: 32px;
    flex-direction: row;
    padding: 8px;
    transition-duration: 0s;
    width: 100%;
    -webkit-box-align: center;
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
}

.css-view-1dbjc4n {
    -webkit-box-align: stretch;
    -webkit-box-direction: normal;
    -webkit-box-orient: vertical;
    align-items: stretch;
    border: 0px solid black;
    box-sizing: border-box;
    display: flex;
    flex-basis: auto;
    flex-direction: column;
    flex-shrink: 0;
    margin: 0px;
    min-height: 0px;
    min-width: 0px;
    padding: 0px;
    position: relative;
    z-index: 0;
}

.r-borderWidth-rs99b7 {
    border-width: 1px;
}

.css-view-1dbjc4n {
    -webkit-box-align: stretch;
    -webkit-box-direction: normal;
    -webkit-box-orient: vertical;
    align-items: stretch;
    border: 0px solid black;
    box-sizing: border-box;
    display: flex;
    flex-basis: auto;
    flex-direction: column;
    flex-shrink: 0;
    margin: 0px;
    min-height: 0px;
    min-width: 0px;
    padding: 0px;
    position: relative;
    z-index: 0;
}

Weird things:

  • The default View style is duplicated and applied twice
  • my border-width style is added to its own class
    • this only seems to happen when there are multiple elements on the screen that use the inline border-width style. Again, I assume this is some kind of micro-optimization.
  • The View style is applied above the border width style. :(

I know this is a pretty specific issue and not a lot of other people are using these libraries in combination. But I was hoping someone here might have some insight before I start hounding the react-native-web and nextjs githubs.

1 Answers

I figured it out.

After hounding the github issues for NextJS and react-native-web, I found this issue which describes the exact same problem.

The offending library was fixed years ago though. Through trial and error, and extensive use of this tool,

https://gist.github.com/necolas/8ee958917db65542784b60323ca6c4bc

I was able to narrow down the problem to this code. Removing it from the app fixed all CSS problems.

import { SafeAreaProvider } from 'react-native-safe-area-context'
<SafeAreaProvider>...</SafeAreaProvider>

Honestly, at this point I don't have any idea why I added SafeAreaProvider. It seems to be required for a non-native SafeAreaView. But the SafeAreaView built into RN + RN-Web is working fine for me.

If someone else has similar issues, I hope this answer will send you in the right direction.

Related