Exploring React Native on Windows
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
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
- Create a CustomNativeModule class, extending ReactContextNativeModuleBase
2. Implement the Name property, required by the abstract class ReactContextNativeModuleBase
4. Register the module. Create a CustomPackage implementing the IReactPackage interface, and add it to the Packages property of your main.cs
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.
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
React native provides three ways to handle asynchronous communication: callbacks, promises and events.
Native modules support a special kind of argument - a callback. It can be invoked from native code (ie to return the result)
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.
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.
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.