Skip to content

Instantly share code, notes, and snippets.

@andrewabest
Last active December 11, 2017 06:30
Show Gist options
  • Save andrewabest/763e0ad37904cfa66e2e5d72aa606d54 to your computer and use it in GitHub Desktop.
Save andrewabest/763e0ad37904cfa66e2e5d72aa606d54 to your computer and use it in GitHub Desktop.
React Native development on Windows

React Native on Windows

So I've started looking into React Native, as mobile development is still a very hot topic, and I would like to do x-plat mobile development that provides a native experience, but doesn't suck for the developer (I'm looking at you Xamarin). I'm a big fan of React, and doing mobile dev that allows hot-reloading during the dev cycle sounds too good to be true.

I'm also going to be building this app with my son, who is 6. It is going to be for him to track his jobs (chores) and income (pocket money), and track savings and goals - encouraging some financial literacy and hopefully letting him reason about the money he makes and what he can do with it! I'm hoping JSX and Javascript will make for a clean and clear way to teach some of the concepts we will use for building the app. Even running through the boilerplate, it was quite simple to explain to him that a <Text> element in the JSX made the app display some text for us. A good start!

If you follow along the Getting Started guide, paying particular attention to the Building Projects with Native Code tab, most of it is pretty straight forward. I'm going to call out some gotchas that I ran across when going through the getting started routine.

One obvious-but-not-obvious gotcha of react native (or any x-plat mobile development) is that if you want to target iOS, you need a mac build machine. So I'm going to be skirting that and starting with android initially.

When you hit Starting The Android Virtual Device, what I ran into was Android Studio demanding I turn off Hyper-V. This is due to it wanting, like most virtualization mechanisms, to act as a hypervisor. I have Hyper-V enabled as I use Docker for Windows, and Docker for Windows uses a Hyper-V VM named MobyLinuxVM to facilitate the various Docker functionalities from Windows. I didn't particularly want to move away from using Docker for Windows, so I went looking for another way to get the emulator working.

Enter the Visual Studio Emulator for Android. This emulator is "Hyper-V compatible", meaning it happily sits side-by-side with Hyper-V. Install this guy, and once installed run it up. You'll need to use it to download an API Level 23 profile, the same as you would have done for the Android Studio emulator - I went with the 5.2" Marshmallow (6.0.0) XXHDPI Phone API Level 23 (Marshmallow, 6.0.0) 1GB.

Right, with the emulator sorted and running, it was time to move onto Testing Our Installation. This is where I ran into another problem. It gets to BUILD SUCCESSFUL, but then fails when attempting to invoke adb.exe. The solution to this was to add C:\Users\andre\AppData\Local\Android\sdk\platform-tools to my Path environmental variable.

And with that sorted, Success!

GoalBox

The app my son and I have decided to create is to be called GoalBox. The broad idea behind it is to enter goals that have a monetary value, then enter jobs / income, and provide an easy-to-understand projection to my son so he understands how he has progressed towards his goal, and how long it may be until he reaches it.

So far you can log in, and enter a goal.

These features have required the following to be implemented:

Navigation

I am currently running React Native 0.43.x, and happened, as if by divine intervention, to use react-navigation. It was a fortuitous choice, as in 0.44.x the React Native team have decided to remove the default Navigator component, and standardize on react-navigation as the community-provided solution of choice.

I like the simple, declarative style of navigation given by the Stack Navigator that allows us to route to top-level components via their class declarations. Very neat!

Forms

I wanted some basic pre-styled form controls to take some of the lifting out of building and styling forms within the app. I've decided Reactive Elements has a good selection, so am rolling with that to begin with.

I ran into an issue after installing these controls (not likely directly caused by the controls / library itself) where during the packaging of the app with react-native run-android the following error would be thrown:

Error:Execution failed for task ':app:processDebugResources'. > java.io.IOException: Could not delete folder “”

The root cause of this seems to be some tool or other having a lock on a file in the android workspace. The solution is to clean the workspace.

Local Storage

I need to store some basic JSON data locally on the device - this will be all the persistence this little app needs. I went roaming for a nice abstraction on top of the base AsyncStorage abstraction provided, but couldn't find any I really liked.

Given how simple my storage needs currently are, I have decided to use AsyncStorage directly, contrary to the advice given in the docs:

It is recommended that you use an abstraction on top of AsyncStorage instead of AsyncStorage directly for anything more than light usage since it operates globally.

I think my usage qualifies as 'light' enough.

Lists

I have a need in the app to display a list of items that gets added to over time. Naively I went and chose the first thing that sounded like a list from the documentation - Listview. It came across as a little WPF-y for a javascript thing - expecially with the typed data source, yuck! After a few twists and turns looking for a SwipeList, I ran across a GitHub issue on a library SwipeListView mentioning FlatList. No crazy abstraction wrapper over the data source? Sign me up!

https://facebook.github.io/react-native/docs/flatlist.html

Keyboard

Once again naively I'd assumed certain interactions would dismiss the keyboard by default. Not so much - after navigations my keyboard would remain on the screen, obstructing view and generally being a nuisance. Enter the Keyboard API - a part of React Native's default APIs. A quick call to Keyboard.dismiss() at the correct time sorted this out quickly enough!

Storage

The AsyncStore needed a little abstraction to be a bit more user friendly, so I've implemented a very basic wrapper around it to handle serialization and keying

import {
    AsyncStorage
} from 'react-native';

const StoreKeys = {
    user:'@GoalBox:user',
    goals:'@GoalBox:goals',
    earnings:'@GoalBox:earnings'
};

class Store {

    static async set(key, item) {
        await AsyncStorage.setItem(key, JSON.stringify(item));
    }

    static async get(key) {
        var storedItem = await AsyncStorage.getItem(key);
        return JSON.parse(storedItem);
    }

    static async reset() {
        Object.keys(StoreKeys).forEach(async (key,index) => {
            await AsyncStorage.removeItem(StoreKeys[key]);
        });
    }
}

export { StoreKeys, Store };

Fairly quick and dirty, but it suits my current use case.

@mishrsud
Copy link

Nice. Coincidentally, I am trying to make a similar app for my son where he can earn "virtual" money and exchange that for real money. Mine is a web app currently as I'm learning the ropes in React world :-)

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