Reason & React-Native

September 12, 2017 0 Comments

Reason & React-Native

 

 

After my last post about Reason it took me some time to get at it again. Learning a new language takes time. You have to get the new syntax, the semantics and the tooling. I'm more of a practical learner, even tho' I like it to read about new tech for days and days, I know I don't really get stuff till I tried it myself and things are always different from how the creators tell you.

Anyway, a few days ago I read about people trying to get Reason to work with React-Native and since React-Native is my thing at the moment, I wanted to try this out.

What

I will tell you how to get up and running with React-Native and Reason. I will use Create-React-Native-App, because using React-Native directly is a bit of a hassle. So no Mac or 75 TB Android SDK required!

Requirements: Linux and an Android or iOS device.

This should also work with MacOS.

How

First install the Node Version Manager.

wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.4/install.sh | bash

Then use it to install Node.js 7 (Node 8 comes with npm 5, which doesn't work with create-react-native-app)

Next step is to install the Create-React-Native-App.

npm i create-react-native-app -g

And use it to create... a React-Native app :D

create-react-native-app my-awesome-app

Some problems that could occur:

react-native-scripts is missing, install it:

npm i react-native-scripts -D

The process that listens for file changes needs some additional configuration, so it can WATCH ALL THE FILES!

This works till you reboot your system:

sudo sysctl -w fs.inotify.max_user_instances=1024
sudo sysctl -w fs.inotify.max_user_watches=12288

Now we have a regular JavaScript based React-Native app, we can start it with npm start and get a QR-code that we need to scan somehow.

We use our mobile device to install the Expo client.

For iOS you can get it from the App Store

For Android you can get it from Google Play

The Expo client lets you scan the QR-code and will open the app created before.

This is all fine and well, but we are here for a Reason!

Lets add some Reason code to our project.

I prefer to put my app-code into a modules folder. So create one inside your my-awesome-app directory and then put an app.re in it!

The my-awesome-app/modules/app.re should have this content:

open ReactNative; let app () => <View style=Style.(style [flex 1., justifyContent `center, alignItems `center])> <Text value="Reason is awesome!" /> </View>;

A simple function that returns some elements, nothing fancy.

But our app doesn't do anything with it right now, so we need to setup a tool chain for the build.

For this we need to add a few devDependencies to our project.

npm i bs-platform reason-react bs-react-native -D

The OCaml compiler is compiled when installing this, which can take some time.

bs stands for BuckleScript, a back-end for the OCaml compiler that we are going to use. It can compile OCaml and Reason into JavaScript. Like Babel can compile the fancy ES2015/16/17 features into old-school JavaScript.

bs-platform requires a bsconfig.json in your my-awesome-app directory with some configuration to get running:

{ "name": "my-awesome-app", "reason": { "react-jsx": 2 }, "bsc-flags": ["-bs-super-errors"], "bs-dependencies": ["bs-react-native", "reason-react"], "sources": [{ "dir": "modules" }]
}

Most important for us is the dir and the name.

We also need to add some scripts to the package.json.

"build": "bsb -make-world -clean-world",
"watch": "bsb -make-world -clean-world -w"

Since we installed bs-platform as a devDependency the bsb command will be available for these scripts.

We can now compile the app.re into an app.js by running

You will find it at my-awesome-app/lib/js/app.js

Create-React-Native-App expects an App.js in your my-awesome-app directory that exports a React component as default, but our component is neither in the right file nor a default export. So we need to use the App.js to connect the Reason world with the JavaScript world.

Open up my-awesome-app/App.js and replace its content with this:

import {app} from "./lib/js/modules/app";
export default app;

Finally everything is in place.

Start the React-Native dev server with:

Scan the provided QR-code with your mobile device and the Expo client and it should show you "Reason is awesome!"

Later you can use npm run watch instead of npm run build while running npm start so everything is compiled when you change something.

Bonus

If you want to use all the nice features of Reason while developing, I recommend using the Reason CLI with Visual Studio Code.

On Linux, install the CLI via npm

npm install -g https://github.com/reasonml/reason-cli/archive/beta-v-1.13.6-bin-linux.tar.gz

And then install the VSCode Reason plugin.

To get the nice auto-format with refmt you need to add "reason.formatOnSave": true to your VSCode configuration.

Wrap Up

So getting started with Reason and React-Native isn't too hard I think. The dev-story for Linux feels a bit more clunky than on MacOS and overall React-Native is much slower on Linux than on MacOS, but that's a React-Native or maybe even a Create-React-Native-App issue.

What's missing, and expected to be missing in such a young language, are binding and/or libraries. I use glamorous-native for my styles in React-Native and it really feels like a big step back to go from writing something like:

<View backgroundColor="red" width="100%">

to writing this:

<View style=Style.(style [backgroundColor "red", widthPct 100.])>

Styling is the bread and butter of a front-end dev, so I don't know if I can take it, haha, but the autocomplete is certainly nice.

For such a very young project I think it's still a phenomenal achievement and worth a try.

Also, if you need some visual help in setting up React-Native, I also made a video course on Skillshare that might help you.

Thanks to Ken Wheeler who wrote a React-Native app in Reason which I took as basis for this post.


Tag cloud