Sayantani Chaudhuri
Technology @ Prospa
7 min readMar 1, 2024

--

photo by Lautaro Andreani on Unsplash

Mastering the Transition: From React Web to React Native Development

My journey from web to mobile developer using React Native has been both challenging and rewarding. With a solid foundation in web development, I understood the basics but had to navigate through a new set of challenges when transitioning to mobile development.

In this blog post, I am going to share how I learned React Native, the hurdles I encountered, and tips for making the transition smoother. This guide is tailored for those who, like me, come from a web development background and are eager to dive into the mobile development world using React Native.

Understanding React Native

React Native, an open-source framework developed by Facebook (now Meta), enables developers to build mobile apps using JavaScript and React. The beauty of React Native lies in its ability to allow for the development of both iOS and Android apps simultaneously with a single codebase. This was particularly appealing to me as it promised a smoother transition from web to mobile development.

To start, I immersed myself in the fundamentals of React Native. Understanding the core concepts such as components, state, and props, which were familiar from React, was straightforward. However, the introduction of mobile-specific components like ScrollView, TouchableHighlight, and the navigation management was new territory. I spent time learning how React Native bridges the gap between web and mobile development, leveraging native components for a seamless user experience.

React Native Architecture and Framework

React Native’s architecture is designed to provide a bridge between JavaScript code and native platform components, enabling developers to write code once and deploy it on multiple platforms.

Following are the key components of React Native architecture:

  1. JavaScript Codebase:

React Native applications are primarily written in JavaScript or TypeScript. Developers write their application logic, UI components, and business logic using JavaScript, leveraging the React library to create reusable UI components.

2. Bridge:

The Bridge is a key architectural component of React Native that enables communication between JavaScript code and native platform code. It consists of two main parts:

— Native Modules: These are JavaScript modules that act as a bridge between JavaScript and native code. Native modules expose native platform APIs to JavaScript code, allowing developers to access platform-specific features such as camera, geolocation, and push notifications.

— JavaScript Runtime: React Native uses JavaScriptCore, the JavaScript engine built into iOS and Android, to execute JavaScript code. JavaScriptCore runs in a separate thread called the “JS thread.”

3. UI Components:

React Native provides a set of UI components that map directly to native UI elements on each platform. These components are rendered using native platform APIs, resulting in a native look and feel. These UI components are highly customizable and can be styled using JavaScript or CSS-like syntax using Flexbox. Developers can also create their own custom UI components to meet specific design requirements.

4. Platform-specific Code:

Despite its cross-platform nature, React Native allows developers to write platform-specific code when necessary. Developers can use platform-specific APIs, libraries, and components to access native functionality not available in React Native out of the box. This enables them to create truly native experiences tailored to each platform.

5. Threading Model:

React Native uses a multi-threaded architecture to improve performance and responsiveness. It separates UI rendering (main thread) from JavaScript execution (JS thread) using the Bridge.

The UI thread is responsible for handling user interactions, layout calculations, and rendering UI components, while the JS thread executes JavaScript code, processes business logic, and communicates with native modules via the Bridge. To ensure smooth performance and prevent UI blocking, React Native employs asynchronous communication between the JS thread and the native platform.

Challenges Faced

As with learning any new skills, there were a number of challenges I faced, which are worth mentioning.

Understanding Native Features: One of the biggest challenges I faced was wrapping my head around native functionalities such as push notifications, how to interact with device’ internal hardware. Unlike web development, mobile apps interact more deeply with the device’s hardware, requiring a different approach.

Performance Optimization: Mobile devices have varying hardware capabilities, which made me realize the importance of optimizing performance to ensure a smooth user experience across all devices. Learning to efficiently manage memory and render components was a steep learning curve.

Design Adaptability: Adapting to mobile design principles was another hurdle. The navigation patterns, gestures, and design elements like Material Design for Android and Human Interface Guidelines for iOS were areas I had to familiarize myself with to create intuitive and user-friendly interfaces.

Overcoming the Challenges

  1. Understanding Native Features:

To handle native functionalities, I learned to integrate native modules and third-party libraries. This not only solved my problem with accessing native features but also helped me understand the bridge between JavaScript and native code. There are different approaches we can take such as

— Built-in Modules: React Native provides a set of built-in modules (also known as APIs or components) that allow us to access native features directly from JavaScript. These modules abstract platform-specific functionality into a unified API that we can use in our React Native app.

Examples of built-in modules include AsyncStorage for storing data locally, and PermissionsAndroid or PermissionsIOS for requesting permissions from the user.

— Native Modules: If the functionality we need is not available in React Native’s built-in modules, we can create our own custom native modules to access platform-specific APIs. Native modules are written in the native language of each platform (Java/Kotlin for Android, Objective-C/Swift for iOS) and expose methods and constants to JavaScript. The main entry point for iOS is AppDelegate.mm and for Android is MainActivity.java

We can create a custom native module in React Native by extending the ReactContextBaseJavaModule class in Android (https://reactnative.dev/docs/native-modules-android) or the RCTEventEmitter class in iOS(https://reactnative.dev/docs/native-modules-ios), and implementing the necessary methods to interact with native functionality. Once we’ve created a native module, we can use the NativeModules API in JavaScript to access its methods and properties from our React Native components.

Third-party Libraries: In addition to React Native’s built-in modules and custom native modules, we can also use third-party libraries to access native features in our React Native app. Many popular libraries provide wrappers around platform-specific APIs, making it easier to integrate native functionality into our app. Examples of third-party libraries include react-native-firebase for using Firebase services, and react-native-push-notification for handling push notifications.

2. Performance Optimization:

Some examples of performance optimization techniques I learned for React Native are listed below

— Rendering optimization focuses on leveraging platform-specific UI components and optimizing layout calculations. Techniques such as using FlatList or SectionList for efficient list rendering, and using the flexbox layout for responsive UI design are common in React Native development.

Styling optimization focuses on reducing layout thrashing and minimizing style recalculations. Using theStyleSheetAPI to create predefined styles, avoiding inline styles, and using flexbox layout for responsive design are recommended practices.

Network performance optimization includes strategies like bundling assets with the app, reducing the size of network requests, and optimizing API responses for mobile devices.

Suppose if our React Native app uses a large number of third-party dependencies, we can optimize bundle size by implementing code splitting. For instance, we can use dynamic imports to load modules asynchronously only when they are needed, reducing the initial bundle size and improving app startup time.

Another approach to improve network performance would be instead of making multiple API requests to fetch data. we can optimize by batching similar requests together using libraries such as axios or Fetch API wrappers. This reduces the number of network round trips and also improves data fetching efficiency by supporting features like request batching, caching, and efficient error handling.

3. Design Adaptability:

I also focused on learning mobile UI/UX design principles. Understanding how to use design tools like Figma, along with React Native’s styling capabilities, creating responsive layouts and intuitive interfaces that cater to mobile users. I found Nielsen Norman Group article very informative and it helped me build a mindset to build apps with simplistic design and to think about good user interfaces.

More tips

To overcome the challenges of learning React Native, I heavily relied on the React Native official documentation, as well as various tutorials and forums like Stack Overflow. The React Native community is vast and supportive, which provides much needed support to novice developers. Keeping abreast with the latest releases, new features, improvements, and changes and best practices helped me a lot.

Besides, having a strong foundation in React is very important and I found epicReact and Frontend Masters training courses very useful.

One of the most important activities for learning anything new is lots of practice and a bit of experimentation. Building small projects and experimenting with different features was crucial. I started with simple applications, gradually incorporating more complex functionalities. This hands-on approach solidified my understanding and made me more confident in my ability to develop mobile apps.

Learning how to debug code is also very crucial. I made it a practice to use debugging tools and techniques like console.log, React Native Debugger, Flipper to diagnose and fix issues in React Native. Also checking for error messages, stack traces, and logging to identify bugs and troubleshoot effectively.

Finally, I learned the process to deploy and submission of the app for store releases (App Store and Google Play Store). Deploying React Native apps involves building platform-specific binaries (APK for Android, IPA for iOS) using build tools like Android Studio or Xcode and distributing them through app stores or over-the-air updates.

Wrapping up

Transitioning from web to mobile development using React Native was an enriching experience that broadened my skill set and opened up new opportunities.

Despite the challenges, the journey was incredibly rewarding. For web developers looking to make the leap into mobile development, React Native is a powerful tool that can ease the transition.

Remember, patience, continuous learning, and hands-on practice are key. Embrace the challenges, and you’ll find yourself growing not just as a mobile developer but as a versatile software developer capable of tackling a wide range of projects.

--

--