So You Want to Write a React Native App?

Published Apr 09, 2018Last updated May 25, 2018
So You Want to Write a React Native App?

After writing and working on several React web apps, a potential business partner told me that he wanted to put a team together that includes expertise on writing mobile applications.

While thinking about where to get started, I stumbled on the Open Movie Database API, a site with a RESTful interface that allows you to query movie titles and details, maintained by volunteers. For a nominal fee, you can make an unlimited number of requests from this site (I didn't need to test whether it's really unlimited.)

Up and Running With React Native

I took an online course several years ago in which I was guided through the task of writing a small app with the Android SDK, but I was hoping to never have to read or write Java again. I also wasn't thrilled about having to write the app twice, once for Android, and again for iOS.

Then I learned that React Native allows one to write an app that will run on both iOS and Android from a single code-base. (You can still write custom code for each platform where necessary, if you have to.) So I could at least write the mobile part in JavaScript with React Native and save myself from having to write the same app twice, once for the Android NDK and again for the iOS SDK.

Android and iOS mobile devices don't run JavaScript in a browser-like environment with event-handling and rendering APIs. Android doesn't even a have a JavaScript interpreter installed by default.

In order to pull this off, a React Native app first has to bootstrap code that will run the JavaScript part in one thread, and run the native rendering and event processing code, "The Root View," in a separate thread called the UI Thread. There is also a UI Thread running custom native code.

Nicalaas Couvrat wrote an excellent in-depth article on what exactly goes on when you start a React Native app. This article goes into even more detail about native modules, threads, and the bridge. The takeaway is that there is some heavy lifting going on behind the scenes before a React Native app can even render "Hello World."

It would be a daunting task to configure this kind of build from scratch. Fortunately, Facebook published the open-source create-react-native-app (CRNA) project that configures a boiler-plate app for you. You install the project globally with npm or yarn, then run "create-react-native-app" from your shell, answer a few questions. When it's finished, you have a minimal app with one screen with a few lines of text to remind you that you might have more work to do.

Expo

CRNA uses the Expo API to allow your app to run on both Android and iOS.

First, you download the Expo client from the Google Play store or Apple store and install it on your device. Next, you start up a packaging server on your desktop by running "yarn start" or "npm run start." The packaging server prints a QR code on the console along with the local URI of your app's manifest.

In my case, that looked like http://192.168.1.x:19000. Finally, you load your app into Expo by pointing it at the QR code on your screen. (Expo needs permission to use your camera to do that. Curiously, I couldn't find a way to type in the URL directly.)

On my Nexus tablet, live reloading worked great. But on my Moto z2 Play, even if I backed out of my app to the Expo client and clicked on the link again, my app just opened where it was on the last screen without reloading. I had to keep shaking my phone and hit the "Reload" item on the developer menu. debug menu

After I ran this command, the script reported that my app is available at https://expo.io/@lsiden/omdb-film-browser. Now, anyone can go to that URL to download it and install it on their Expo client. You can chose whether or not you want your project to be listed or unlisted. Even if you make it unlisted, anyone with the URL can access it.

Going Native

OK, so you got your app to look good and work in the Expo client. Your app is still on training wheels. You want people to be able to find and install your app directly from the Google Play Store without having to install Expo first.

When you created your app with 'create-react-native-app', it installed the package.json tasks "build:android" and "build:ios". This builds your APK or iOS binary on the Expo server. It takes time, so get a cup of coffee. When it's done, the script prints the URI of your APK or iOS package which you then downloaded to your desktop.

If you don't save this link or download it right away, you can still find it by going to https://expo.io/builds. You may have to sign in again. You will see a history of all of your builds and a link to download or view the log of each build. However, don't expect to find a link to this page anywhere on the Expo site. I couldn't.

Once I had the APK, I put it in my Dropbox account, then downloaded it to my phone, found it on my phone with my file manager app, and installed it. To do this, you'll have to give your OS permission to install apps from "unknown" sources, meaning sources other than the Google Play Store. Once installed, it worked exactly as it had in the Expo client, only it loaded faster.

I don't own an iPhone, so I'll have to leave testing on iOS to a later date.

Going Beta

So now I have an APK and verified that it works on my phone, but I want to get it tested on more devices before I announce it on my social media feeds. Also, I don't expect my app's users to download the APK sideload. Fortunately, the App Store makes this easy with a beta-testing program. First, you sign onto Google and go to the Google Play Store app publishing pages.

I found The Play Store app-publishing section to be confusing at first. After filling out several forms, I found the page to upload my APK. Once I got it uploaded, it did not say anywhere that I would have to wait for my app to be reviewed before it could be published even in beta, nor how I would be contacted once it had been approved.

I had to resort to a live chat with the online help desk. The rep told me that I had to go to the Settings section and opt in to be notified. I would have expected to have to ask to be notified when my app gets approved. When I search in my mailbox now, I can't find any email that notified me, so I think I had to go back to the Play Store to check. Fortunately, it did not take that long.

Now I had to look for the link I could distribute to beta-testers. To find it, I had to go into the Release Management tab, click on Manage Beta, then open the Manage testers folder. There is was, at the bottom of the section, labeled "Opt-in URL."

It turns out that unless your app prints money, people aren't going to flock to beta-test it for you. I searched for "beta-test Android apps" and found this sub-Reddit titled AndroidAppTesters where people post links to apps that they would like to have tested but it doesn't seem to be very active.

Google has an interesting service called Firebase where you can upload your APK and have it tested automatically for a fee on an array devices for a reasonable fee. It says you can test it on up to five real devices and 10 virtual devices for free, but I could only get the test to work when I selected one device.

I got back a few screen shots with a report that nothing crashed. To get past my home page, I would have to load my app into the Android Dev Studio and create a testing script to upload with my APK so that the test engine would type into the search bar and click on a result.

While I'm sure this would be highly useful for a commercial app, my app is really for demo, so I prefer to have feedback from human beings who volunteer to load and run my app. I may have to post a small bounty to find a reasonable number of volunteers for this.

Conclusion

That's as far as I've gotten so far. Here are a few screen shots:

Seearch and results screen

Film Details screen

About screen

In the next few days, I plan to publish some more post that describe some of the issues I encountered while building this app, and how I overcame them. In particular, I plan to cover these topics:

  • Unit testing
  • Debugging
  • Logging
  • Performance issues
  • Navigation
  • Configuring eslint
Discover and read more posts from Lawrence Siden
get started