Category: JavaScript

What to expect

  • Why this post?
  • The original project, the idea
  • The choices and preparation
  • The solution implemented with React Native and Expo
  • Published app
  • Conclusion

Why this post?

My experience with React Native and Expo was not straightforward, I had few challenges and frustrations and I wanted to share with you how I resolved them.

The original project, the idea

I started to work with JavaScript in 2017 so I needed a way to learn. I created a small solution to track my reading progress with React, Redux & Saga and Spring Boot: library-web, library-resources and library-api. Deploying live such a stack seemed too much for one person, a mobile solution looked simpler and the natural choice was React Native.

The choices and preparation

I followed Getting Started:

  • Expo CLI Quickstart – Advertised as “If you are coming from a web background”
  • React Native CLI Quickstart – Advertised as “If you are familiar with native development”

Initially I wanted to reuse some java code so I went with the second option.

React Native CLI Quickstart

I installed Android Studio, Watchman and I configured the ANDROID_HOME environment variable:

I generated the sample project and I got lost. Setup looked complex for a beginner: React Native, Android, Gradle, React Native + Android. If everything works from the start, that’s great but if something is not working I would not know which part to check first. I see it appropriate for the ones who know more about React Native and Android.

Expo CLI Quickstart

I chose “blank – minimal dependencies to run and an empty root component” and it looked familiar again.

Common for both

You should:

  • know how to start an emulator and connect a real device. I recommend to start an emulator from command line like

  • know how to deploy the app on emulator and a real device
  • know how to debug the code

Watch out for:

  • You have enough hardware resources. I noticed that 8Gb are not enough, my system run really, really slow. 16Gb is much better.
  • I found a possible alternative: Android_x86 with VirtualBox but I did not manage to install it.
  • I had to comment out the last two lines from Android SDK bash setup, see more on Android SDK command line issue

The solution implemented with React Native and Expo

I wanted to keep as much as possible from library-web so the steps were:

  • Create a new project: MyReads
  • Configure i18next
  • Migrate presentational components
  • Migrate redux code
  • Migrate container components
  • Remove API calls and used local storage

Configure i18next

I decided to go with json translation files, the default file format for i18next, to make things simpler:

Translation files loading logic was added in Localizer.js:

and application entry point depends on it:

In this step the implementation of the render method contains dummy code to make sure that translation logic works.

I also used babel-root-slash-import to have absolute imports and I replace it later with babel-plugin-module-resolver.

Original source code: MyReads 01-configure-i18next tag

Migrate presentational components

The next step was to migrate the presentational components, like the one that display the error messages:

and render it several times in App.js:

After I deployed the app I noticed an issue with android status bar, it was covered completely by my application:

android status bar covered image

Original source code: MyReads 02-migrate-first-component tag

The fix was to use a margin for Android platform:

android status bar visible image

Original source code: MyReads 03-configure-app-top-margin tag

I continued with flexbox layout and I had the next headache. My understanding was that I have to use flex: 1 for every component that needs to layout it’s children with flexbox so I defined the following styles:

and I applied them for my needs, first in a custom component:

and then on application component:

The result was not the expected one:

flexbox issue image

After searching for few mornings and trying different things, I noticed that in my case the fix was to use flex: 1 only at application component and removed for the other components:

and the result was what I wanted:

flexbox fixed image

Original source code: MyReads 04-flexbox-issue tag

Migrate Redux code

After I migrated few react components and I got a feeling about how things are working in react native, I wanted to use the other building blocks from the previous project, like redux, when I got the next headache:

redux integration issue image

It turned out that it was my mistake, I updated package.json with latest versions of everything. The fix was to pay attention of react native documentation and use the right versions:

I also noticed that react-redux ^6.0.1 is the max version that works with redux ^4.0.1.

Original source code: MyReads 06-redux-integration tag

Migrate container components

After fixing the redux integration, I did not experienced any other major issues except of my bugs.
Original source code: MyReads 07-migrate-container-components tag

Remove API calls and use local storage

The last step was to remove API calls and use local storage. In documentation is mentioned that it is deprecated and the suggestion is to use React Native Community AsyncStorage, but it doesn’t work with expo.
I added below the logic for book handling to have a sense on what’s going on:

Original source code: MyReads 08-use-local-storage tag

Published app

The can download the final solution from Google Play for the moment, I do not have yet a build for iOS.

Conclusion

I had a lot of issues because of my lack of experience. After I fixed the infrastructure problems, I did not experienced any other major headaches. I believe that at least for simple apps that not need platform specific code, React Native and Expo can be a good match.