React Native is an open-source framework developed by Facebook for building mobile applications using JavaScript and React.
With React Native, developers can create native apps for iOS, Android, and other platforms using a single codebase. This means that there’s no need of having to write separately.
React Native offers a number of advantages over traditional frameworks, like allowing developers to build apps using JavaScript and CSS.
This makes starting with mobile app development a piece of cake!
React Native has a highly modular and flexible architecture, this enables you to reuse components across different projects. It reduces workflow and improves code quality [check debugging], and you can focus on creating new features.
So…Get creative and delve into: Splash Screens in React Native, animations, vision camera, video, image picker, vector icons and maps!
The Old Architecture used to work by using The Bridge. The consumer can read the data, deserialize it and execute the required operations. However, there are some limitations to it:
The New Architecture advocates the JavaScript Interface (JSI). The JSI allows a JavaScript object to hold a reference to a C++ [back and forth].
This enables invoking methods directly on it. Like a C++ object can now ask a JavaScript one to execute a method in the JavaScript [back and forth].
This unlocked several benefits:
These are the foundations for upcoming enhancements. For example, it has been possible to develop a new renderer which will be explored next.
There’re some major changes that are already settled in since mid-2022.
First and foremost, if you want to start migrating into React Natives new architecture, just click here The Migration Guide and follow its steps.
Hands on for creating a custom Fabric component or a TurboModule with a step-by-step approach. It guides you so as to adapt your existing app or library to use the New React Native Architecture.
Find painstaking articles of the React Native internals. The Fabric section helps you grasp the rendering pipeline in the New Architecture world.
React Native 0.68 is what has been chosen as support for the Fabric Renderer and the TurboModule system. If you want to be up-to-date with the latest.
You can fin in React Native’s blog posts “the Architecture section to the website, where you can find several in-depth guides about internals of the new systems.”
We’ll cover the following new features of the React Native’s New Architecture:
There’s a caveat. All of these are iterating as we speak, so CTA▶️ Use it and give feedback! 🔛
The Fabric Renderer and TurboModule system are two separate technologies developed by Facebook to improve the performance and UX of their mobile applications.
CodeGen is not a mandatory tool. Nevertheless, if you believe that time is of the essence, it’s a must for you.
The Fabric Renderer is a cross-platform UI rendering engine that allows for faster rendering and smoother animations on mobile devices. It uses a declarative approach to building user interfaces.
Fabric Native Components instead of Legacy Native Components allows us to embrace React Natives New Architecture benefits [taken from React Native’s blog post]:
Follow the next steps for creating a Fabric Native Component:
Once done, the component is ready for the app.
In order to keep the component decoupled from the app, it’s a good idea to define the module separately and then add it as a dependency to your app later. This also allows its release as open-source.
For this guide, you are going to create a Fabric Native Component that centers some text on the screen.
RTNCenteredText
.js
, ios
, and android
.You should see this:
├── MyApp
└── RTNCenteredText
├── android
├── ios
└── js
The New React Native Architecture requires interfaces specified in a typed dialect of JavaScript (either Flow or TypeScript).
Codegen works to generate code in C++, Objective-C++, and JS. There are two musts for the file:
<MODULE_NAME>NativeComponent
, with a .js
or .jsx
extension when using Flow, or a .ts
, or .tsx
extension when using TypeScript. Codegen only looks for files matching this pattern.HostComponent
object.Find specifications of the RTNCenteredText
component in both Flow and TypeScript. Create a RTNCenteredTextNativeComponent
file with the proper extension in the js
folder.
import type {ViewProps} from 'ViewPropTypes';
import type {HostComponent} from 'react-native';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
export interface NativeProps extends ViewProps {
text?: string;
// add other props here
}
export default codegenNativeComponent<NativeProps>(
'RTNCenteredText',
) as HostComponent<NativeProps>;
Flow:
// @flow strict-local
import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
import type {HostComponent} from 'react-native';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
type NativeProps = $ReadOnly<{|
...ViewProps,
text: ?string,
// add other props here
|}>;
export default (codegenNativeComponent<NativeProps>(
'RTNCenteredText',
): HostComponent<NativeProps>);
You need imports that are required by every Fabric Native Component:
HostComponent
: type the exported component needs to conform to.codegenNativeComponent
function: responsible to actually register the component in the JavaScript runtime.The second section of the files contains the Props of the component information that let you customize React Native components. In this case, you want to control the text
property of the component.
Finally, codegenNativeComponent
generic function, called passing the name of the component.
Next, you need to add some configuration for CodeGen and auto-linking shared between iOS and Android.
The shared configuration is a package.json
file that will be used by yarn when installing your module. Create the package.json
file in the root of the RTNCenteredText
directory.
{
"name": "rtn-centered-text",
"version": "0.0.1",
"description": "Showcase a Fabric Native Component with a centered text",
"react-native": "js/index",
"source": "js/index",
"files": [
"js",
"android",
"ios",
"rtn-centered-text.podspec",
"!android/build",
"!ios/build",
"!**/__tests__",
"!**/__fixtures__",
"!**/__mocks__"
],
"keywords": ["react-native", "ios", "android"],
"repository": "https://github.com/<your_github_handle>/rtn-centered-text",
"author": "<Your Name> <your_email@your_provider.com> (https://github.com/<your_github_handle>)",
"license": "MIT",
"bugs": {
"url": "https://github.com/<your_github_handle>/rtn-centered-text/issues"
},
"homepage": "https://github.com/<your_github_handle>/rtn-centered-text#readme",
"devDependencies": {},
"peerDependencies": {
"react": "*",
"react-native": "*"
},
"codegenConfig": {
"name": "RTNCenteredTextSpecs",
"type": "components",
"jsSrcsDir": "js"
}
}
The upper part contains descriptive information. Make sure to make any needed update embedded in <>
: replace all the occurrences of the <your_github_handle>
, <Your Name>
, and <your_email@your_provider.com>
tokens.
Then there are the dependencies for this package. You’ll need react
and react-native
.
Finally, the CodeGen configuration is specified by the codegenConfig
field. It contains an array of libraries, each of which is defined by three other fields:
name
: The name of the library. By convention, you should add the Spec
suffix.type
: The type of module contained by this package. In this case, it is a Fabric Native Component, thus the value to use is components
.jsSrcsDir
: the relative path to access the js
specification that is parsed by Codegen..podspec
fileFor iOS, you’ll need to create a rtn-centered-text.podspec
file to define the module as a dependency for your app. It will stay in the root of RTNCenteredText
, with the ios
folder.
The file will look like this:
require "json"
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
Pod::Spec.new do |s|
s.name = "rtn-centered-text"
s.version = package["version"]
s.summary = package["description"]
s.description = package["description"]
s.homepage = package["homepage"]
s.license = package["license"]
s.platforms = { :ios => "11.0" }
s.author = package["author"]
s.source = { :git => package["repository"], :tag => "#{s.version}" }
s.source_files = "ios/**/*.{h,m,mm,swift}"
install_modules_dependencies(s)
end
The .podspec
file has to be a sibling of the package.json
file, and its name is the one we set in the package.json
‘s name
property: rtn-centered-text
.
The first part of the file prepares some variables that we use throughout the file. Then, there is a section that contains some information used to configure the pod, like its name, version, and description.
All the requirements for the New Architecture have been encapsulated in the install_modules_dependencies
. It also automatically installs the React-Core
dependency in the old architecture.
build.gradle
and the ReactPackage
classTo prepare Android to run CodeGen you have to:
build.gradle
file.ReactPackage
interface.At the end of these steps, the android
folder should look like this:
android
├── build.gradle
└── src
└── main
└── java
└── com
└── rtncenteredtext
└── CenteredTextPackage.java
buildscript {
ext.safeExtGet = {prop, fallback ->
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
repositories {
google()
gradlePluginPortal()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
}
}
apply plugin: 'com.android.library'
apply plugin: 'com.facebook.react'
android {
compileSdkVersion safeExtGet('compileSdkVersion', 33)
namespace "com.rtncenteredtext"
defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 21)
targetSdkVersion safeExtGet('targetSdkVersion', 33)
buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true")
}
}
repositories {
mavenCentral()
google()
}
dependencies {
implementation 'com.facebook.react:react-native'
}
ReactPackage
classThen, you need a class that implements the ReactPackage
interface. To run the CodeGen process, you don’t have to completely implement the React Native Package class.
Create an android/src/main/java/com/rtncenteredtext
folder and, inside that folder, create a CenteredTextPackage.java
file.
package com.rtncenteredtext;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Collections;
import java.util.List;
public class CenteredTextPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
The ReactPackage
interface is used by React Native to understand what native classes the app has to use for the ViewManager
and Native Modules
exported by the library.
It requires you to write some native code to connect the JavaScript side of the Component to what is offered by the platforms. Requiring two steps:
When developing a React Native app that uses a Fabric Native Component, the app is accountable for generating the code using CodeGen. However, when developing a Fabric Component as a library, it needs to reference the generated code.
Find more information on Codegen here. And if you want to dig into iOS follow this link!
The TurboModule system is a technology that optimizes the performance of native modules in React Native applications.
Native modules are pieces of code written in platform-specific languages such as Java or Objective-C that can be called from JavaScript code in a React Native application.
It reduces their startup time and memory usage, making React Native apps faster and more responsive. Please, get hands-on and codes to run HERE!
Two technologies that help to make Facebook’s mobile apps more efficient for users and devs.
Click if you want to keep on exploring!
There’s a lot to discover and keep on improving, that’s why we are adamant on receiving your feedback and iterate! React Native is a powerful and versatile framework that is well-suited for building a wide range of mobile applications.
Whether you’re a seasoned developer or just starting out, React Native is definitely worth considering for your next mobile app project. Check our posts and Instagram to find out more!
Leave a Reply