Skip to content

Instantly share code, notes, and snippets.

@walaura
Created June 6, 2019 21:58
Show Gist options
  • Save walaura/94c6679ac789211770707c567b199926 to your computer and use it in GitHub Desktop.
Save walaura/94c6679ac789211770707c567b199926 to your computer and use it in GitHub Desktop.

I picked up React Native as a web developer and here's what I've learned

For the last couple weeks, I've been building a RN app at work. It's a bit of a monster, with filesystem access, background downloads, and push notifications. This wasn't my first time using React but!! It was my first time using RN. Which is scary. Here's some stuff I've learned that was sorta news to me:

Why use React Native?

The web is pretty awesome, PWAs are gaining ground and honestly going all the way to the app store to install an app feels like a bit of a journey. You might wanna consider if the web fits what you wanna do before going this route.

In our case we had two requirements that drove this decision: We wanted the project to be in app stores and we wanted very elaborate offline & background functionality. This is very experimental on web but a solved issue since day one of mobile apps. React native runs on top of native apps we have full control of so

It's not the web

On the web, standard React eventually generates an HTML-based website. This is how you can use plain CSS and by using refs you can directly call DOM functions on your components.

Native is a bit of a different beast. Despite using React's syntax – and unlike libraries like Cordova – RN never gives you HTML, or DOM Elements or CSS, but rather orchestrates native views directly on your mobile OS. This is pretty awesome! Native UI is incredibly optimised and runs like a charm. If you are used to struggling to get 60 fps animations on the web this is a whole new and incredibly refreshing world where that's the default

[aladdin pic]

Setup

Use expo it rules

CSS

React native comes with a built in StyleSheet module. it handles styling for you. This rules because you don't have to argue ever again about what css-in-js solution to use. It's also bad because StyleSheet is so similar to CSS you might think you are writing CSS.

The built in documentation on how to style things is very good but I wanna get into the big changes first

It's pretty much like css-in-js

Your styles are a javascript object with camelcase properties. If you have used emotion or styled-components you'll feel right at home with this way of working

But everything is a flexbox

Since all StyleSheet does is talk to the underlying OS you are restricted in ways to do layout compared to CSS. If you want to float something (For example to wrap an image to the side of some text) you are completely out of luck. Same goes for using CSS grid! Ours is quite a special case but since our React native app had to render very type-heavy articles we decided to render those in a webview and wrap it in our react native app.

And there's no cascade or selectors

You apply your styles directly to your components. You can't style children based on their type or have things like hover or disabled states or :before / :after pseuds.

This sounds super limiting but in reality having a well architected and modular app with small components will take care of a lot of this for you.

None of your styles cascade, this can make your CSS more predictable but also a bit of a pain. We remediated this by using react context to encapsulate style properties we wanted to cascade down like theme colors. Context is ideal for this because you can have multiple contexts in the same screen for different nodes, almost working like css variables.

The loss of the cascade is not that big of a deal as it might seem except for a single but very important use case:

Text

All text you want to render in React native has to be <Text>Wrapped in a text tag</Text> and it will display in the system font at 16px.

You can of course style your text to have any font and size you wanna, but text comes so many shapes and sizes that you should be prepared to have a ton of variations. In our app we ended up having a single file for all our styled text elements but I'm not sure this is the best structure.

Fonts

You'll probably wanna use custom fonts! Especially now that all apps are white on black with a bunch of lines and there is literally no other way than type to tell them apart. This is where loading fonts comes in! And you don't have to deal with @font-face rules which is pretty neat.

Sadly everything else is pain. Your font files will live inside your Android and iOS projects and here's where it gets hairy: To use a font in Android you will reference its filename, to use it on iOS you will reference its Postscript name. Don't know what that is? Don't worry, I didn't either. It's this thing:

ps thing

SVG

You don't get to use normal SVGs in your app. they are not supported by the image element. This is obviously very bad especially for icons and such.

For complex shapes and such you can convert them into bitmaps, 90s style. You'll probably wanna set up a build pipeline to churn them out for you. All the assets in your app will be downloaded upfront so file size is not as big of a critical consideration as it is on web (but don't go bananas!)

If you want to remotely import SVG that's a bit trickier but not impossible! There are several libraries that will do this for you by essentially chucking them in a webview.

For everything else (I'm doing this!) You can use react-native svg to use SVGs inside your code. The way this works is it exports react native versions of everything in an svg and you can use these and it draws the proper views for you

code sample

Having SVGs be first class citizens in React with props and animation and everything has changed the way i see all SVGs. i always knew they were markup but having to directly adjust them myself now has given me lots of ideas for cool things I can do with them.

At the end of the day react-native svg is a very elaborate hack that gives you views so it can also be used as a low level drawing library for things like lines and circles and whatnot! Your imagination is the limit!

A good way to assess what SVG loader to use is by asking yourself how messed up will things be if this doesn't load? so for example you might want icons to be inline SVGs but big hero images to be remotely downloaded. Be aware that some things will always be messed up and that some of your users will never see images anyway because they use screen readers or have poor eyesight or they just can't figure out what an arrow coming out of a box in a circle is supposed to mean.

Always make sure you have proper accessible descriptors for all your images! And provide sensible fallbacks if an image can't load (For example, in a hero, code in a background color that gives the text enough contrast)

Typescript

Type safety is important! Especially if you don't wanna write tests. With that in mind it's important to have an open mind and remember that all typed JS compiles down to vanilla untyped JS when it actually runs. This is important to keep in mind because the type definitions for React Native itself and many of its modules are pretty bad

If you wanna animate elements, Animate will helpfully cast them to any. Some of the type definitions will be outdated, others will be typed but less 'safe' than you expected them to be (react-navigation doesn't know of it's own routes and takes any string)

Having full type coverage is a good tool for ensuring stable and maintainable code but at the end of the day it's not the only one. in my short experience, obsessing over it in RN apps is a quick path to frustration. Sometimes a response does just contain any and you have to deal with that.

Animation

If you have tried to animate things using React on the web you probably already know it's hard. Animating things in react native is harder but also more rewarding??

If you want a specific effect chances are it's been done already. React-navigation does pretty serviceable transitions and you can even upgrade to connected animation using TODO. If you need even more all of this is built over the same built in animation library you can use.

The core concept of Animated is that you have values you can update as a result of user actions (like a drag), using time, or just updating them yourself. You can plug those values as style properties and RN does all the heavy lifting for you and makes things buttery smooth.

animation example
@jesseyuen
Copy link

jesseyuen commented Jun 9, 2019

Reads well bud!

I hate the sound of using bitmaps in a project. Gah!! What resolution did you have to make them to ensure they look crips on a modern device? @2x, @3x?

I'd like to read some link suggestions that you found useful to 'get started' as a newbie, and maybe the baseline dependencies/requirements I'd need to be able to get started. The article currently does a really good job of demystifying RN but doesn't point me in the direction to personally get started as a lazy developer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment