This Is Nowhere: Head-First Into React Native
Jan 05, 2019 19:17

I had created a starter version of the This Is Nowhere client in plain HTML and JavaScript, and I had done an iOS version of the spin-off Bloomsday app, which used some similar technologies. The live date was getting closer and so it was time to start thinking about building the real clients for the production.

The thing is, because of the GPS permissions issues we had experienced in user testing, just using a browser-based “app” wasn’t going to work for us. Testing with just a handful of savvy friends had led to technical support headaches - a live show with hundreds of random members of the public was going to be a nightmare. So we were gong to need to go native on both iOS and Android. While I’m fairly familiar with iOS development, I would need to learn a whole new language and development environment to build for Android. While I had heard good things about Kotlin (doing to Java what Swift had done with Objective-C) I decided to go in a different direction:

It was time to finally try React Native.

React Native

React is a JavaScript framework developed by Facebook to help them to build their complex interfaces. It’s become quite popular in the front-end JavaScript community, and in fact I had already learned a bit of React while teaching it in a Lighthouse Labs boot camp. React Native keeps all the JavaScript back-end of regular React, but does some magic to replace the HTML output of regular React with native Android and iOS components. So you can use JavaScript and a component-based approach and build faster, more native-feeling apps than with previous, clunkier, embedded-browser-based approaches.

One great aspect of using React Native was that I would only have to build one application to support both iOS and Android. Since I was the entire development team, I was really worried about having to support late-breaking changes in multiple codebases. It’s often hard enough to get things working in one codebase! Having to keep multiple codebases in multiple languages would be a nightmare.

An added bonus to using React Native was that I could recycle a lot of the JavaScript code I had already written for the original testing app - things like the distance calculations, the logic of the “stars” display, and all the ways of interacting with the server.

Only needing one single codebase for native apps in both iOS and Android, and the ability to write in JavaScript is a powerful combination - and it more than makes up for a lot of the flakiness of React Native.

And React Native is pretty flaky sometimes: it brings together all the eccentricity of iOS development, the clunkiness of Android development, and the teetering chaos of the JavaScript NPM world. The actual development experience is pretty smooth and even enjoyable, but often you can see through the cracks to all the duct tape and twine holding everything together.

Using Atom

I’ve been using EMACS as my main coding environment since the early 2000s, but I’d been hearing a lot about some of the newer text editors, so decided to try GitHub’s ATOM editor for this project. Sometimes I wondered if I was pushing it too hard, breaking in a new coding environment as well as a new framework. Thankfully it was easy to work with, and I could set it up to use EMACS keyboard shortcuts for a lot of things.

(Yes this is low-res and kind of blurred intentionally - you really don't want to see my bad code!)

ECMA6

There was another big first for me on this project: while I’ve been using regular JavaScript since it first came out in the mid 1990s, this was my long overdue first proper project using the ECMA6 flavour of JavaScript. Although the new ways of declaring functions took some getting used to, I immediately appreciated the new async / await way to handle asynchronous stuff.

So, this was my first React Native app and my first big ECMA6 codebase. I’ve found that if I really want to learn new things, the best way is to throw myself headfirst into a real project using them. Thankfully I already knew what the app was supposed to do and look like, and I had already done two different implementations in other languages. So I could instead concentrate on learning how to do things in React Native.

And It Worked!

It’s certainly not the best coded React Native app, but it works! Because almost everything in the app is triggered by time and location, I didn’t use any navigation frameworks, and instead just had a large case statement checking state and rendering a lot of sub-components for the different screens. Getting the tappable-cover slide-down clues interface to work properly was kind of a hacky mess, but then again React Native is kind of a hacky mess too. The component-based architecture meant that I could wrap up the hacky mess into a nice box and not worry about it once it was working properly.

Getting the app to actually compile and run on iOS and Android devices was a bit of an adventure in hunting down weird error messages and obscure configurations - including plenty of "start a new app from scratch and copy all your source files over" as well as way too much "delete your node_modules folder and run npm install yet again". However, once everything was working properly, I had nearly identical apps running on both iOS and Android devices - extra impressive since I didn't even have ready access to my own Android device to test properly.

React Native may a teetering Jenga tower held together with duct tape and twine, but you can use it to launch rockets!

I’m now working on an updated version of the app, replacing the navigation and clues with photos from and audience contributions to each of the scenes, as a sort of “memento” of the production. It’s giving me the chance to go back to React Native with more experience (and less panic) and look at doing things more properly.

After finishing this project, I read a number of articles about companies and teams having trouble with React Native. The big takeaway is that if you really want native-feeling and high performance UI and UX with lots of refinement and subtlety, and if you have the resources for it, it’s better to skip React Native and work directly in iOS and Android - but in this case I was the only resource, and the app’s UI was very simple. For This Is Nowhere, React Native was the perfect choice.

Previous:
This Is Nowhere: Bloomsday Halifax
Oct 30, 2018 22:26
Next:
Presentations About NowHere
Mar 09, 2019 15:12