From React to React Native, or There and Back
Mobile development through the eyes of a web developer
In this article, I will talk about how I ended up working on a mobile application project despite only having experience in web development. What’s inside? — the difficulties encountered, mistakes made and tips on how you could protect yourself from repeating them.
Intro
I wanted to give React native a try for a long time, especially because I assumed that it’s just a React but extremely tailored for mobiles. But there was never enough time. And here I was presented with just the perfect opportunity!
It started like the Hobbit’s journey…
Expo vs React Native
At the start of a React Native project you have 2 options: React Native CLI and Expo CLI. Both will make you work with React native, and the only meaningful difference is that if you create an app using React Native CLI you can change the native code (Java/Kotlin/Swift/Objective C).
Initially, the project that I had to work on was supposed to be a very simple application for presenting & viewing information in the format of cards/tabs/tables. Therefore, we opted for Expo. Mainly due to simplicity, not needing to dig into the native part of the application, and the ability to limit ourselves to React (Native) components. Another significant advantage of Expo is that it is easier to update apps in stores compared to React Native (Play Market/App Store). And in case you need to expand the functionality, it is possible to migrate from Expo to React Native, allowing you to access the native part of the application — for example, WebRTC.
How to use Expo
Install Expo CLI:
npm install --global expo-cli
To create an application using the Expo CLI, use this command:
expo init app-name
To run the application, use the following command:
expo start
The easiest way to run apps on iOS/Android devices is to use the Expo Go app. With Expo Go you won’t even need a MacOS to run your app on iOS.
When you run expo start, Expo CLI starts a Metro Bundler, which is an HTTP server that compiles the JavaScript code of the app and serves it to the Expo Go app on your device (Note that your computer & mobile device have to be on the same WiFi network). When you update your code, Expo Go will reload your app automatically.
There are two approaches to building applications with Expo: managed and bare workflows.
Managed Workflow makes building applications as simple as possible. This approach doesn’t require much use of Xcode or Android Studio (although they are useful for debugging!) — you mostly write JavaScript code and manage configuration such as app icon and splash screen, using app.json/app.config.js or Config Plugins. Expo SDK provides an increasingly comprehensive set of APIs that allows access to mobile device’s resources such as camera, biometric authentication, file system, haptics, etc. Applications that use the Expo CLI to run on the device are Managed Workflow apps.
Bare workflow allows you to modify the native part of the application and provides the same set of APIs as Managed Workflow, but without the help of Expo. To run Bare workflow applications you use yarn ios and yarn android commands to start the JavaScript bundler server and build the project binary. This requires Xcode or Android Studio, depending on the platform. Apps built with React Native CLI are Bare Workflow apps.
Unfortunately (or fortunately, depending how you look at it hehe!), with the growth of the project each developer wonders if, maybe, you don’t even need Expo in terms of Managed workflow? And I think that’s true.
Expo provides an opportunity to migrate from Managed workflow to Bare workflow. To do this, you need to run the expo eject command. This command will turn your application into a pure React Native application, leaving only those Expo SDK APIs that you have already used in the project. To add another Expo SDK library, you can use expo install.
And that’s where the problems begin
In my case, the transition to Bare workflow happened on its own and I did not notice it happening. However, since this transition went smoothly, I continued to work with my application as if it was still a Managed Workflow application, i.e. the “.apk” was built and launched using Expo tools.
The problems started suddenly when it had become necessary to use WebRTC technologies in the project — Zoom SDK, to be specific. And then something like “Mordor: a guide for Hobbits” began — after going through a bunch of texts and a huge number of forums and articles, I got the impression that I came to React Native so as not to use it. Because the development process was really slow.
And then, after unsuccessfully stumbling around, I fell & woke up with a cast formed of Java/Kotlin & Swift/Objective C (remove the one you don’t like).
Omitting the chilling details of diving into the world of Java and Swift, I can only say that the necessary functions were written, but then the realization came… When starting and even building the application, I cannot access the written functions that have access to the native part of the application (Zoom SDK in particular). Having bogged down in a ton of documentation, I nevertheless solved the problem. But at what cost? I had to forget about VS Code for some time, alternating between Android Studio and XCode. At the same time, testing and debugging involved either use of an emulator or building and installing the application on the device. The only consolation was the fact that it already looked and felt like mobile development (Although, I myself was not very mobile during these times. Looks like I still got deceived somewhere).
React vs React Native
But back to React Native: as you guessed it, the journey did not just take 20 minutes.
Initially, I thought that React Native is the same React, only Native. After a fairly long period of time, I can say that I was not so far from the truth.
Do you have problems with semantic layouts and do everything on divs instead? You can’t live without hooks inside other hooks? Your PM is beating you with a stick for your inline styles, but you still keep using them regardless?
Then React Native is for you!
Here you can write the entire application using View-components, the same hooks and even more — there is no CSS here! Which almost justifies your self-expression with inline-styles.
Some wonderful React Native’s peculiarities
1. By default, all elements are laid out as flex-column, unlike the browser, where by default display:flex sets the elements as a row.
2. In some cases Android and iOS components are rendered differently. For example, calendar and switch. Therefore, if you need to follow the design, you will have to use your own custom components.
3. Another noteworthy feature is the animation. In the browser, to simplify, it all comes down to keyframe, transition and transform. In the case of React Native, however, everything starts shining with new, never before experienced colors of pain. In general, this looks like a keyframe with provided values and animation times.
“Animated” provides three types of animation. Each animation type provides a specific animation curve that controls how your values animate from their start value to their end value:
- Animated.decay() starts at initial speed and gradually decelerates to a complete stop.
- Animated.spring() provides a basic physical model of a spring.
- Animated.timing() animates a value over time with easing functions.
In most cases, you will use “timing()”. The default is a symmetrical easyInOut curve that conveys a gradual acceleration of the object to full speed and ends with a gradual deceleration to a complete stop.
4. React Native allows you to render existing sites using a WebView, i.e. a React Native app can play the role of a browser. In my case, I used this method to render the service available on the web version with full functionality in order to save time and not reinvent the wheel.
At the moment, WebView is a component of a third-party library, however, it’s too useful not to talk about it.
In general, it has something similar to iframe:
5. Moving away from the topic of React Native and touching on the topic of mobile development in general, I should mention the features of working with the Google API.
When working through Expo, you must specify separate keys for the application in the Expo ecosystem and for the standalone application (the name says it all — this is an application that is no longer limited to the Expo ecosystem and exists on its own). In addition, you need to create separate keys for iOS and Android. So, you need at least 2 keys to publish and build your app, but if you don’t want to give up on Expo then the number of keys goes up to 4 (Never laugh at live dragons!).
Summing up, I would like to say that React Native has a large community. And even if support for some of the features the community likes (such as the checkbox for iOS) ceases to exist, some especially active developers are very quickly expanding the npm base and adding the necessary solutions.
In conclusion
Should you try React Native if you have experience with React (or even if you don’t)?
In my opinion it’s definitely worth it, but (and it’s a big “but”) if you are faced with the prospect of creating a large and complex application you better get to learning Java/Kotlin/Swift/ObjectiveC, because sooner or later you will have to encounter Smaug sleeping on the gold the native part. And then you won’t get by with just a React Native.
“Go back? No good at all! Go sideways? Impossible! Go forward? Only thing to do! On we go!” More interesting articles soon, follow & clap here at the Intspirit’s blog.