Skip to main content
Dashlane Logo

Exploring React Native on Windows

  |  Paola Ducolin

This is the second in our series of blog posts around Windows desktop technologies. After exploring Electron, we decided to spend time investigating a brand new technology: React Native for Windows.

One of our goals was to assess how much mutualization can happen between a Windows React Native code and a Web ReactJS code.

We want to share our experience and our evaluation of the technology, considering that this was done a few months ago and that technology evolves a lot in time.

What is React Native

React Native is an open-source mobile application framework created by Facebook. It is used to develop applications mainly for Android and iOS by enabling developers to use native platform capabilities along with ReactJS, a popular web UI framework. Two years ago, Microsoft released a first alpha version of Facebook's React Native that added support for Windows 10 SDK, which allows building UWP apps. Microsoft Skype is one of the largest React Native applications in the world.

Exploring React Native for Windows

React Native uses Javascript (or TypeScript) to describe the UI, which is translated into a native component. On Windows, React Native components become WPF or UWP components at runtime.

When exploring this technology, we wanted to make sure that we were able to:

  • Provide custom components
  • Have asynchronous communication between frontend and backend
  • Reuse our web code base as much as possible

Custom components

Additional functionalities can be easily provided using custom modules. A module is a C# class that extends the ReactContextNativeModuleBase class and implements some methods callable by Javascript. A custom module can also provide additional UI components.

Adding native methods callable from Javascript
Let's see how to implement a simple custom module that provides methods callable from Javascript.

  1. Create a CustomNativeModule class, extending ReactContextNativeModuleBase

2. Implement the Name property, required by the abstract class ReactContextNativeModuleBase

3. To expose a method to JavaScript a .NET method must be annotated using the [ReactMethod] attribute. The return type of bridge methods is always void. The React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events

4. Register the module. Create a CustomPackage implementing the IReactPackage interface, and add it to the Packages property of your main.cs

5. To make it simpler to access to the new functionality from JavaScript, wrap the native module in a JavaScript module

6. Now the native module's methods are callable from Javascript

Adding a custom view
React Native enables wrapping up purely native view components for seamless integration with the application. In this guide we will implement a QrCodeView.

1. Create a ReactQrCodeViewManager class, extending SimpleViewManager with generic argument Border. Border is the type of the framework element managed by the manager: this will be the custom native view. The Name property is used to reference the native view type from JavaScript. The Border type is used to support border radii on images: the background of the Border is set to an ImageSource that represents the QrCode.

2. Implement overridden method CreateViewIntance. Views are created in the CreateViewInstance method, the view should initialize itself in its default state, any properties will be set via a follow up call to UpdateView.

3. Expose view property setters using [ReactProp] attribute. Here we expose data, used to generate the qr code.

4. The final step on native side is to register the ViewManager to the application, this happens in a similar way to NativeModules, via the applications package member function CreateViewManagers

The very final step is to create the JavaScript module that defines the interface between .NET and JavaScript for the users of your new view. Much of the effort is handled by the internal React code in .NET and JavaScript and all that is left for you is to describe the propTypes, that are used for checking the validity of a user's use of the native view.

Asynchronous communication
React native provides three ways to handle asynchronous communication: callbacks, promises and events.

Callbacks
Native modules support a special kind of argument - a callback. It can be invoked from native code (ie to return the result)

Promises
Native modules can also fulfill a promise. When the last method of a bridged native method is IPromise, the corresponding JS method will return a JS Promise object. This can simplify JS code, using async/await syntax.

Sending Events
We can send events to JavaScript, without being invoked, using the RTCDeviceEventEmitter attached to the context

JavaScript modules can register to receive events by addListener from NativeEventEmitter wrapped module.

Web code reuse
When we started exploring React Native, our hope was to be able to use 100% of our Web app ReactJS code to build a native desktop app. Don't judge us, we were totally newbie on this technology, and the name sounded close enough! Well, the result was a resounding no. ReactJS is not exactly React Native. Here's a detailed description of the differences, so you can avoid making the same mistakes we did.

TLDR; we found that the UI syntax has many differences in the base UI components. There are projects whose goal is to have shared codebase between ReactJS and React Native.

Conclusions

On the UI side, React Native was a modern and fun framework to develop on, with a modular architecture by design.

Performance and memory footprint was another advantage over Electron: our prototype used as little as 80MB of RAM, versus 250-300MB of the Electron prototype.

Still, when we explored the technology, it was too new to Windows. Microsoft is currently working to improve performance and stabilize the technology by reimplementing its core in C++, and next milestones are planned for June 2020.

We took the time to investigate new technologies. After exploring React Native and Electron, we will also look into .Net UWP.

Stay tuned!

Sources links:

Sign up to receive news and updates about Dashlane