It’s been an interesting couple weeks diving into React-Native.
First of all, why did I try React Native? I’ve been toying with an app idea and wanted to give app development another shot. It’s been a few years since I last tried. Initially I built the api with Nodejs and a semi functional frontend with regular React. Looking at the trending ‘react’ google searches, React-Native is massive. Ok, let’s give it a shot.
I started by trying out the offical tutorial including the getting started. https://facebook.github.io/react-native/docs/tutorial.html
The tutorial gets you to clone the template with ‘create-react-native-app’ This includes a setup with Expo and you get started by installing the Expo app on your phone and connecting via the integration being locally hosted on your network. Fairly quick to get up and running.
I made may way through the tutorial and got to the point where I could send some data back and forth between my app and my api. It was fairly quick to get started and after the syntax of the react-native jsx elements and the different ways of attaching onPress or onChangeText etc.
Roadblocks started once I started to deviate from the tutorial.
I’m pretty awful at following tutorials and get side tracked pretty hard. I like to get a feel for things and then explore a little, referring back to the tutorial when I get stuck.
My app requires the use of a camera. Ok so lets go ahead and add the react-native-camera package. The setup looks pretty straightforward. ‘yarn add react-native-camera’ and then run ‘react-native link’. My console just printed out: ‘undefined is not an object (evaluating ‘CameraManager.Aspect’)’.
Googling that with react-native leads me to believe that the react-native link hasn’t worked properly. Ok. Lets have a look at my project. Why didn’t it work?
This is all it would output. Which made me think it worked, right? I mean there’s no error and it scanned the folders I think? Well no.. It didn’t Running react-native link with no other output means there was nothing it could link. There were some manual steps that you could use to setup the package. It lists adding some permissions and settings into specific android files.. Which I assumed at the time hadn’t been setup properly by the link. I followed these steps and it still didn’t work in my app, running on Expo.
Now remember when I setup my app using the create-react-native command line from the tutorial? Well this doesn’t exactly create everything you actually need. None of the IOS or android settings/gradles/files/manifests are included at all. I found this out by doing a ‘react-native init’ in a different directory, where I was presented with all the files I needed. Ok time to migrate all my code to the new directory.
While I’m here I hook up my app to Expo so I can run it easily. I run react-native link and I get the nice message saying it found some still to link!
Ok, time to run the app, open the camera screen and.. ‘undefined is not an object (evaluating ‘CameraManager.Aspect’)’.
Wait what? Turns out, after ages of searching stack overflow and GitHub, Expo itself doesn’t support native libraries and can’t access the camera. It’s more of a vm sort of thing, there are API’s available within the Expo environment, but no bueno with the native library. Ok so I need to remove Expo and build straight to my phone, when I was building games with Unity a few years ago it was fairly straightforward right?
I went ahead and installed Android Studio, resolved all the errors and mismatched packages and versions that needed to get the build compiling without any issues. I found I needed to install ADB to connect my phone (Nexus 6p). I was then prompted to install the Java Runtime Environment on my first run on ‘react-native run-android’.
Ok Ill go ahead and get the latest one. JDK 9. Well that wasn’t the right thing to do, as far as I can tell the latest version supported is actually only JDK8. Ok Go ahead and uninstall JDK 9 and install JDK 8. Run ‘react-native run-android’ and voilà! The app compiles, it boots up on my phone and I see a wonderful camera screen! Easy!
Time to refactor
The next issue I had was mostly due to me not understanding how the flex style works within the app. I had decided to move the camera screen of the main ‘App.js’ component and into its own component where it belongs. I make sure I add the new component to the entry component. But suddenly my camera is gone, it wont render.
The ‘Take photo’ button is there, but the camera isn’t. It’s rendering the button at the top of the screen, so maybe the styles are a bit weird and the cameras off the top or something. Ok, what happens when I try to take a photo from the camera I cant see?
“Error: takePictureAsync: Expected a Camera component”
Most results on this error point me to missing permissions in my Android.manifest. This isn’t the issue, the camera was JUST working.
I debug the code using chrome. I can see my ‘take photo’ code being run. I can see my camera object that I binded attached. I can inspect the object, I can see the permissions are OK.
When migrating to the standalone component, I had removed the style from the parent ‘View’. The flex styles it turns out, need all parent objects to have a flex index, so without it the camera wouldn’t appear on screen correctly. Even though the camera is defined, if it’s not on screen it doesn’t render.
Currently I’m struggling to read a recorded video back out of the cache correctly. This involved installing react-native-fs (regular fs doesn’t work in react-native). I’ve not quite worked this out yet, and issue about an ‘Invalid continuation byte’ which I’m not 100% sure about. I decided to take a break from trying to fix that to do this quick write up.
So far my experience with react-native has been.. not great. I’ve not struggled with a technology like this for a long time. I’ll admit that a few of my issues could have been solved with more general app development experience. But going from web development with React to React-Native is certainly not a quick migration. I’ll continue building this app using React-Native until I either finish it, or get frustrated enough to swap to something else.
Heres some quick tl:dr points:
The React tutorial is somewhat misleading and once you want to do anything slightly more complex, you need to be aware that a large portion of the boilerplate you need is missing. I don’t think it’s a good idea to teach this using Expo.
The error feedback is severely lacking. Most of the time the errors are not caused directly by a mistake that’s been made, they are a symptom of your mistake, but the message isn’t related. More immediate feedback, or even warnings would go a long way.
It’s still a very greenfield technology and it can be a struggle to find very specific issues that you are personally having with it.
It is nice actually building the app using the React workflow and JSX (I’m yet to try and integrate typescript.)