Transitioning from React to React Native
5 min read
When I learnt that I was going to be moving to our mobile app development team, one of the first things I did was to try googling for things React engineers should know when moving to React Native. I strangely didn't find a lot of content around this - perhaps because I wasn't searching for the right thing, or perhaps because no one's really created much content around this yet.
I therefore thought it might be a good idea to periodically write down some thoughts around things I learn or come across that I think web devs transitioning to mobile app development would find useful to know.
Here's the first post which covers 3 things that I learnt over the course of last week that I wish I had learnt sooner. I would definitely have been able to realise these sooner if I had just spent some time reading the official React Native documentation, but I don't really operate that way! I find it easier to read documentation once I have some context and have tried building something myself and have it fail, as I find it a lot easier to get the "aha" moment that way. Writing it down in a blog post like this then helps to consolidate my learnings. 😄
1. CSS does not really cascade
CSS tends to mostly work the same way in React Native, as it does on web. The main thing to note however, is that elements don't really inherit style properties from their parent containers in the same way.
So for instance, if you have something like View
encapsulating a couple of Text
elements, the child Text
elements will not inherit the textAlign
style property from View
.
<View style={{ textAlign: 'center' }}>
<Text>Blah blah</Text> // this will not be center aligned!
<Text>Blah blah</Text> // this will not be center aligned!
</View>
What you'd need to do is apply the style to the Text
elements directly:
<View>
<Text style={{ textAlign: 'center' }}>Blah blah</Text>
<Text style={{ textAlign: 'center' }}>Blah blah</Text>
</View>
This obviously starts to get tedious after a while, so there are a few patterns to get around this that basically involving abstracting out the style you want.
Option 1: Abstracting the style out to a reusable class through Stylesheet
- still repetitive though
;<View>
<Text style={styles.centerText}>Blah blah</Text>
<Text style={styles.centerText}>Blah blah</Text>
</View>
const styles = StyleSheet.create({
centerText: {
textAlign: 'center',
},
})
Option 2: Creating custom components - less repetitive, but more convoluted
export const RegularCenterText = ({ style, children }: Props) => (
<Text style={[fontStyles.textReg, style]}>
{children}
</Text>
);
export const fontStyles = StyleSheet.create({
textReg: {
color: 'black,
fontSize: 16,
lineHeight: 24,
textAlign: 'center',
},
)
2. Use native List Views to render lists more efficiently
The official React Native documents will explain this better than I will so refer to this document. In essence, the idea behind this is that the screen sizes on mobile devices are relatively smaller than web browsers for Mac or PCs. Your app can therefore be optimised by only loading what is visible on the screen at any one time. There's no real point in rendering a list with say a 1000 rows, if only 5 are visible on the screen at any one time.
Native components like FlatList
or SectionList
allow us to do this easily by taking in a data array, and allowing us to define how to render a single item.
3. Think about the touchable area on screen
This was something I hadn't considered at all, until I saw a PR from another senior engineer which included a prop called hitSlop
. The name itself doesn't give a lot away, so I did some googling which opened up a whole new area of mobile development that I'm ashamed to say, had not crossed my mind at all.
To take a step back, when developing on React Native, there are certain native components you can use to define whether certain elements are interactable. For instance, there's a Pressable
component that allows you to define what happens onPress
but also onLongPress
lasting more than 500ms. The thing to consider here is what you're making "pressable". If it's a small word, e.g. "link", it might be difficult for the user to actually click on it depending on the size of their finger, what device they are using, magnification settings etc etc.
The thing we can do here is to expand the interactable area by using hitSlop
. This allows us to sets the additional [rectangular] area around an element in which the interaction can still be detected. Read this document if you want to learn more.
Are you a React Native developer? Do you have any other tips for me or any other improvement suggestions to my realisations above? Let me know on Twitter or Instagram @bionicjulia.