Moving Foward With React Native

From Here To There

Pulasthi Aberathne
7 min readFeb 20, 2023

REACT NATIVE HAS BECOME ONE OF THE MOST POPULAR WAYS FOR MOBILE DEVELOPMENT AND ONE OF THE BEST WAYS FOR EVERY SCALE OF APPLICATION DEVELOPMENT. LET’S TAKE A PEEK UNDER THE HOOD OF PLATFORM ARCHITECTURE.

Mobile Application Development

There are three major components in the React Native Platform

1. JS Bundle

JavaScript code is typically bundled into a single file called a “JS bundle” that contains all the code necessary to run the app. The JS bundle is generated by the Metro bundler, which is the default bundler used by React Native.

The JS bundle is typically generated during development and is updated whenever changes are made to the code. In production, the JS bundle is pre-built and shipped with the app, so it’s important to keep the bundle size as small as possible to minimize download times for users.

To configure the JS bundle, you can modify the metro.config.js file in your project's root directory. For example, to enable minification for release builds, you can add the following code to the metro.config.js file:

module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
minify: true, // enable minification
},
}),
},
};

2. Native UI

React Native allows developers to create native user interfaces for mobile apps using JavaScript and React, rather than using platform-specific languages like Java or Swift. This is made possible through a bridge that communicates between JavaScript and native code, allowing developers to write UI code in JavaScript that is then translated into the platform-specific native code.

React Native provides a set of built-in UI components that can be used to create a native user interface, such as View, Text, Image, Button, and ScrollView. These components are designed to look and behave like their native counterparts on both iOS and Android, providing a consistent and familiar user experience across platforms.

3. Shadow Tree

The term “shadow tree” refers to the virtual representation of the UI hierarchy that is created by the framework. The shadow tree is a concept that is shared with React, the web-based counterpart of React Native.

The shadow tree represents the current state of the UI and is generated from the components and their props that are defined in the code. When changes are made to the UI, the shadow tree is updated accordingly, and the actual native components on the device or emulator are updated to match the new state of the shadow tree.

The shadow tree is created by the React Native runtime and is a purely virtual representation of the UI. It is not visible to the user and does not directly correspond to the actual native components on the screen.

React Native Architecture
Previous React Native Architecture

BRIDGE . . . ?

In React Native, a bridge is a communication mechanism that allows JavaScript code to interact with the native platform’s code. React Native apps have two major parts: JavaScript code and native code. The bridge is what connects these two parts.

The bridge is responsible for transferring data between the JavaScript code and the native code. When a React Native app is running, any communication between JavaScript and the native code goes through the bridge. For example, when a user interacts with a component on the screen, the JavaScript code generates an event that is sent to the native code through the bridge. The native code then processes the event and sends the result back to the JavaScript code through the bridge.

The bridge is an important component of React Native because it allows developers to build apps that have a native look and feel, while still using JavaScript to write the code. This means that developers can build cross-platform apps that run on both iOS and Android, while still having access to platform-specific features.

What’s New with React Native

The bridge has upgraded in the new version of React Native. Bridge is limited for some applications and has some issues in the previous version and there are lots of limitations when it comes to the compatibility with different platforms of hardware. To mitigate these issues there are two new factors introduced to React Native.

New architecture
The New Architecture in React Native

1. JavaScript Interface (JSI)

The JavaScript Interface in React Native is a feature that allows developers to define a two-way communication between JavaScript code and native modules written in Java or Objective-C. This means that developers can write native modules that expose functionality to JavaScript code, and also write JavaScript code that can call methods on these native modules.

The JavaScript Interface provides a way for React Native apps to access native functionality that is not available through the JavaScript environment. For example, if you want to access the device’s camera or accelerometer, you can write a native module that exposes this functionality to JavaScript code.

To define a JavaScript Interface in React Native, you need to create a native module that extends the ReactContextBaseJavaModule class in Java or NSObject in Objective-C. You then define methods on this module that can be called from JavaScript code using the NativeModules API in React Native.

For example, here is a simple native module written in Java that exposes a greet method to JavaScript code:

public class GreetingModule extends ReactContextBaseJavaModule {
@Override
public String getName() {
return "Greeting";
}

@ReactMethod
public void greet(String name, Promise promise) {
String greeting = "Hello, " + name + "!";
promise.resolve(greeting);
}
}

In this example, the getName the method returns the name of the module that will be used in the JavaScript code. The greet the method is annotated with @ReactMethod, which makes it accessible from JavaScript code. This method takes a String argument name and a Promise object, and returns a greeting message to the Promise object.

In JavaScript code, you can call the greet method using the NativeModules API like this:

import { NativeModules } from 'react-native';

const { Greeting } = NativeModules;

Greeting.greet('John').then((greeting) => {
console.log(greeting);
});

In this example, we import the NativeModules API and access the Greeting module. We then call the greet method on this module, passing in the name John. The method returns Promise that resolves to the greeting message, which we log to the console.

This is just a simple example of how the JavaScript Interface works in React Native. Using this feature, you can define complex native modules that expose a wide range of functionality to your React Native app.

2. Fabric

The goal of Fabric is to improve the performance, reliability, and maintainability of React Native apps. It is a re-architecture of the core components and layout system of React Native and is designed to be more efficient and flexible than the previous implementation.

Some of the benefits of using Fabric in React Native include:

  • Improved performance: Fabric is optimized for faster rendering and better memory usage, which can lead to significant improvements in app performance.
  • Better reliability: Fabric includes improved error handling and recovery mechanisms, which can help to prevent crashes and improve the overall stability of your app.
  • Improved maintainability: Fabric is designed to be more modular and extensible than the previous implementation, which can make it easier to add new features or fix issues in your app.

In general, it’s a good idea to use Fabric to take advantage of its improved performance and reliability. However, if there is an existing app that is working well with the previous implementation of React Native, developers may want to test your app with Fabric first to make sure that it still works as expected.

3. Turbo Modules

The goal of Turbo Modules is to improve the startup time and memory usage of React Native apps. It achieves this by optimizing the way that native modules are loaded and initialized, and by reducing the amount of memory that is used to store native module metadata.

The traditional way of loading and executing native modules in React Native involves using the requireNativeComponent function, which can be slow and memory-intensive. Turbo Modules provides an alternative approach that uses a new format for storing native module metadata and a new module resolution algorithm that is more efficient.

To use Turbo Modules in your React Native app, you need to upgrade to version 0.64 or later, and opt-in by setting the turboModule flag to true in your app's configuration. Once you've done this, React Native will automatically generate Turbo Module artifacts for all of your native modules, and use them to load and execute native code.

4. CodeGen

The goal of CodeGen is to allow you to write code in a higher-level language and have it automatically translated into native code that is optimized for the platform you’re targeting. This can help to improve the performance and maintainability of your app, as you can use familiar JavaScript syntax and tools to write your code, and rely on CodeGen to generate efficient native code for you.

CodeGen works by using a combination of static analysis and runtime code generation to translate your JavaScript code into native code. It includes a set of predefined macros that can be used to generate common native patterns, as well as a way to define your own custom macros for more complex cases.

To use CodeGen in your React Native app, you need to enable the feature by setting the codegen flag to true in your app's configuration. Once you've done this, you can use the @codegen decorator to mark functions that should be translated into native code. These functions can include predefined macros, custom macros, or a combination of both.

These are just a few of the new features that have been introduced in recent versions of React Native. As the framework continues to evolve, it’s likely that we’ll see even more new features and improvements that can help to make building mobile apps with React Native even easier and more efficient.

Follow the official documentation for more information

--

--

Pulasthi Aberathne

I am Software Engineer. A visionary who believes the psychological strength over physical empowerment.