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!)


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.

This Is Nowhere: Bloomsday Halifax
Oct 30, 2018 22:26
Presentations About NowHere
Mar 09, 2019 15:12
Other Blog Posts
My Expanded Twitter Thread about BurgerWeek 2021 This Is Nowhere: The Server Side Building a React Native App Without Tears - Part 3 Building a React Native App Without Tears - Part 2 Building a React Native App Without Tears (Mostly) This Is Nowhere: The Memento Edition This Is Nowhere: Aspects of Accessibility Presentations About NowHere This Is Nowhere: Head-First Into React Native This Is Nowhere: Bloomsday Halifax This Is Nowhere: Why an HTML/JavaScript Single-Page App With GPS Is A Bad Idea This Is Nowhere: GPS and Wayfinding and More UX This Is Nowhere: The Single-Button UX This Is Nowhere: Don’t Just Stand There! This Is Nowhere: Finding My Duck Finding Burgers Fast: My DIY Halifax Burger Week Site "This is Nowhere" at PodCamp Halifax 2018 The Diary Diaries: Fixing Remembary's Facebook Connection Special Leap Day Edition of "Some Weird Things About Time" What's Up With Remembary Can't get pg_dump To Work Now That Heroku Has Upgraded Postgresql to 9.4? The Best Thing I Ever Did To Promote My App If You Build It, They WON'T Come #deployaday, My Big Hairy Plan for 2015 Extracting Plain Text from an NSAttributedString My Year of "Hits" Part 2: Remembary Rolling My Year of "Hits" Part 1: Remembary Rises (and Stumbles) Handy Little Test Method to Check for Translations in Rails Apps My Suddenly Slow-Waking MacBook Air Indie App PR: Keeping Control of Your Tone A Quick Note on 'clone' in Rails 3.2 My eBook Apps 2: iOS, JavaScript, and Ruby My eBook Apps 1: Introduction Quick Tip: No Sound on Mountain Lion My Upcoming Talk at PodcampHFX 2012: My Year of "Hits" Building at the Speed of Funny Screencast Tips Remembary's Cool New Picture Support Indie App PR 2: Keeping On Top Of User Feedback Indie App PR 1: How to Handle an App Disaster Giles Bowkett Diary Project 2 Remembary Video Congratulations! Welcome to Your Nightmare! How My iPad App Remembary Took Off Why You Should Have an App in the App Store (Even If You Probably Won't Make Any Money) PodCampHFX Remembary Presentation - Part 3 How I Used MailChimp Autoresponders to Promote Remembary PodCampHFX Remembary Presentation Part 2 PodCampHFX Remembary Presentation Part 1 Why AdWords Ads Don't Work for iPad Apps Remembary is Sponsoring PodcampHFX Why Can't I Resize my Views in Interface Builder? Momento and Remembary Concerning Remembary iPad-Friendly eBooks of Gracian's Art of Worldly Wisdom Project Report: PTOS2 A Quick Note on Encryption We're all LUsers Thoughts on HAML Friday Afternoon Hack - Getting Beyond the Basics Halifax Friday Hack and Back to Basics Quote from Wil Shipley FutureRuby Make Web Not War Busy Week I: Toronto Ruby Job Fair Employment.nil - the Toronto Ruby Job Fair Code Count: Ruby on Rails vs. C#/ASP.NET A Brief Note on Twitter The Hub Halifax and Mobile Tech for Social Change Deep Thoughts on Microsoft From The Accordion Guy The Two Kinds of Defensive Programming Presentation - Fixing Careerious: From C#/.NET to Ruby on Rails Enterprise! Presenting at Ruby on Rails Project Night - May 7th New Name and New Look for Careerious/Clearfit FutureRuby and More From Unspace Health Tips for Programmers This tables meme won't die Careerious - Ruby and Rails vs. C#/.NET Yeah I Use Tables For Layout, So Sue Me The Different Kinds of Done Giles Bowkett's RubyFringe presentation OfficeTime: Great Time-Tracking App for OS X Back With A New Look Non-DRY Feed torontorb Keeping Your Sanity With The Command Design Pattern shindigital Is All Grown Up! (according to the spambots) Startup Stars? I'm so bored! The Magic Words for RMagick Jennifer from Operations You see? Naming is HARD Business Software as Process Documentation Deployment note: 'execve failed' Steve Jobs on Market Research Why Canada Is Better for Entrepreneurs "Program first and blog second" Toronto Tech Collage The MacBook Air Is A Roadster RubyFringe! Quote of the Week: Steve Yegge Starting Up: Cards Great design tool: Starting Up: The Logo Quotes Of The Day: Hedge Fund Interview TSOT Ruby / Rails Presentation Night - Part 1 Moneyworks: Accounting Software for Canadians on OS X Starting Up: The Name Nice logo, but why is your site so bland? Welcome to