A Beginner's Guide to Mobile Development in React Native with Expo
Tags: reactnative, expo, typescript, mobile
Published: 2022-03-23 15:34:06

## Intro
This is a guide getting you through setting up a React Native project. However, this guide won't go in details with React, so if you're new to React, I recommend you to check out this [getting started with react guide.](https://beta.reactjs.org/)

[Here is a link for what your code should look like, when you are done.](https://github.com/IT-Minds/first-mobile-app/tree/main)

## React Native and Expo
React Native is a framework for writing cross-platform native apps. 

Expo is a set of tools and services built around React Native and native platforms that help you develop, build and deploy iOS and Android apps from the same JavaScript/TypeScript codebase. The alternative would be to build each app in xCode and Android studio, which is very cumbersome.

## Installation

### Prerequisites
You need to have [node and npm installed](https://nodejs.org/en/download/), and [yarn](https://classic.yarnpkg.com/en/docs/install#mac-stable) is optional, but recommended.


Then we have to install Expo, through npm:
```shell
# Install the command line tools
npm install --global expo-cli
```

Now, we're ready to make a project. If you installed yarn, write:
```shell
expo init first-app
```
or with npm
```shell
expo init first-app --npm
```
From here, you will be prompted with a few options for your project. I recommend choosing a managed workflow as this enables us to release the app in Expo, without an Apple developer account for iOS. I chose the template "blank (typescript)", as can be seen in the picture below. If you're new, you could also use the "tab" template. This has built-in navigation.

![Init expo app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6st9i4kdksc3721ouyb7.png)
 
You now have a project. In your terminal, you can navigate to the project's directory with 'cd first-app'. Your project structure should look like this: 

![File structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zm4excvr0ynziwouhne.png)

Now, you can run the project by writing:
```shell
yarn start
```
or
```shell
npm run start
```
And it will look something like this:
![App template iPhone](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msfw5uoswjecam322oh9.png)

You can either press w, to see your app in your browser, or you can scan the QR code which redirects you to download an app called [Expo go](https://expo.dev/client). This allows you to view the app while you develop it, which is something I would recommend. 

![Initial app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l370yjyi80gfritav8r6.png)
 

You now have a running app in React Native. In the next section, we are going to look at how native APIs work.  
 
 
## Native APIs
As we choose a "managed workflow", we're building everything with Expo. This comes with some [limitations](https://docs.expo.dev/introduction/why-not-expo/). If you need a native API which isn't on the [list of supported APIs](https://docs.expo.dev/versions/latest/) (there is 100+ native APIs), you can switch to a bare workflow in which you can write your own native code. 
Below is a comparison between a managed and bare workflow: 
![Managed and bare workflow comparison](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1yk3bvoeroi2ayfzq73f.png)

### Implementing native APIs
As an example, let's make a page that shows our battery percentage and GPS location.

Let's start with a [battery](https://docs.expo.dev/versions/v44.0.0/sdk/battery) component. We install it with:

```shell
expo install expo-battery
```
First off, we'll work on showing the battery percentage. We need the API 'getPowerStateAsync'. We'll call when a component mount, and voilá - we have the phone's battery percentage:

```jsx
const [battery, setBattery] = useState<number>(0);

  useEffect(() => {
    Battery.getBatteryLevelAsync().then(b => setBattery(b));
  }, []);
```
We can show it in our view like this:
```jsx
return (
    <View style={styles.container}>
      <Text>Battery {(battery * 100).toFixed(0)}%</Text>
      <StatusBar style="auto" backgroundColor={"black"}/>
    </View>
  );
```
![Battery 42%](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vrt12szsca44mq34sk2i.png)

Now, let's make a component that looks at the power mode of a phone. Imagine that you have a power-hungry feature which you want to disable when in low power mode (like animation).
We can get the power state from the same API, like this:

```jsx
const [lowPoweredState, setLowPoweredState] = useState<boolean | null>(null);

  useEffect(() => {
    Battery.getPowerStateAsync().then(bs => setLowPoweredState(bs.lowPowerMode));
  }, [])
```
We can now carry out some conditional rendering, based on the power state:

```jsx
  if (lowPoweredState === null) return <Text>Getting info from your phone...</Text>;
  return (
    <Text>Battery state: {lowPoweredState ?
      "i am a static text replacement" :
      "I AM A POWER HUNGRY ANIMATION"}
   </Text>);
```
![Rendering based on power state](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft4z9v54ilim0xcifac8.png)

To stay up to date, when the phone changed from a low powered state to a normal one, we can add a listener in useEffects like this:

```jsx
const batteryModeSubscriber = Battery.addLowPowerModeListener(b => setLowPoweredState(b.lowPowerMode))
return () => batteryModeSubscriber.remove();
```

Our app will now always render based on the power state.

## Publishing our app
Normally, you think of publishing an app to App Store and Google Play store. In order to do this, you need an [Apple developer account](https://developer.apple.com/programs/)(100$ yearly subscription) or a [Google Play developer account](https://play.google.com/apps/publish/signup)(25$ one time fee) account. You can read more about building and releasing your app [here](https://docs.expo.dev/build/setup/).


## You're an app developer 
You have now started on your first React Native app in Expo. This is the same tool which is used for creating apps like Facebook, Instagram, Coinbase, shopify, Tesla, Uber Eats and many more. You can read more on Expo here: https://docs.expo.dev/ or check out an open source app here: https://github.com/withspectrum/spectrum
and checkout an enterprise boilerplate here: https://github.com/infinitered/ignite