React Native: A Mobile Developer’s Perspective
Does React Native truly fulfill the needs of clients? Is the development time using React Native reduced significantly?
Update: We wrote a summary for you: Insights to React Native for Decision Takers
React Native has become one of the most sought out development frameworks on the top freelancing sites. So, as part of keeping up with the latest demand of new technologies, we wanted to discover for ourselves, if the praise of React Native around the web is really justified?
Ergo, we gathered four developers, two iOS, two Android developer with little knowledge of ES6 and no knowledge at all of React to learn and implement a project using React Native. In order to compare the efforts to produce a similar-looking app, we implemented a project that was previously implemented natively for both the iOS and Android platform by Modeso.
Exploring React Native
At the very start of our learning process, we tried two tutorials which covered the very basics of React Native and we felt that we were mostly copying code and not understanding much behind the code, so we switched our learning tactic and followed Stephen Grider’s Udemy course which provided us with all the basic knowledge to kickstart a project and how to handle data changes using redux.
Our biggest hinderance during the learning phase was the use of Atom and Nuclide, the official recommend IDE’s by Facebook to develop React Native. There was no auto-complete, no syntax error highlighting even with eslint activated, no debugging and for a new developer coming from IDE’s as Xcode or Android Studio, this can be very frustrating. We added some add-ons to Atom, and still, it was not enough. While searching for add-ons, we stumped upon articles supporting the switch from Atom to VSCode and we gladly switched and were extremely rewarded.
Kick-Starting our Project
Adding Sentry and the Node Module Issues
Our first real challenge was to get npm to install Sentry on Windows, it would not run the project on Android, nothing we did would make it run. Even after following the solutions posted on GitHub, only after copying the npm modules from a Mac to Windows it was possible to run the project. We did not discover this until later on after fruitless attempts to install another package on Windows and we then resorted to copying the npm modules.
Going Ahead in the First Sprint
For initial navigation, we used router-flux v3.x, which provided us with a simple navigation between screens although it had performance issues.
Most of the tasks in our first sprint were shifted to our next sprint due to the many obstacles that we faced with styling components which is very similar to CSS, something we native developers are not used to. In addition to the many incomprehensible crashes that ended up being simply fixed by restarting the package manager.
One of our action items from our first sprint was to work peer programming until we became accustomed to React Native, a decision that helped speed up implementation.
One tasks in the project was to add a list with indexing. We first implemented it with the now deprecated ListView and we noticed that upon fast scroll or jumping to a specific index there is a noticeable delay causing a white empty screen. We then switched to use a SectionList which greatly improved the performance. But nevertheless, we can momentarily see blank content.
From there, after a steep learning curve, our project progress speed up, this was partially due to the many great articles on Medium, Hackernoon and a prominent writer of React Native, Spencer Carli. In addition, to us becoming more accustomed to React Native syntax, profiling using Perf Monitor, getting familiar with the extensive chrome debugger and understanding the crashes.
Our app consists mainly of custom UI components and different kinds of charts, natively we used each platform’s UI components and some libraries with slight modifications to implement them. In React Native we implemented the most part ourselves and used libraries as an underlying layer. The React Native implementation took longer, but not considerably, and it had the same look-and-feel and smooth animations as those implemented natively. Only slight difference was in the gradient UI effect of one of the charts.
One of the things that we greatly enjoyed using is Redux. Although initially it may seem hard to grasp, it can be used to implement anything related to data changes. The only downside was that live inspection was not possible with Redux V2.x.
Unit Testing on React Native Projects
For unit tests in React Native, the default testing framework is Jest, but their documentation was greatly lacking. In spite of the fact we followed the official documentation of jest and redux, the unit tests did not pass. Moreover, the snapshot tests that initially passed failed as we added more packages in components. Furthermore it was not clear where should we place the mocks, nothing was mentioned in the documentation and as we searched and looked for more resources, we came across more frameworks and it became more confusing which are essential and which are complementary like the debate between using Enzyme and Jest. Unit testing in React Native was unnecessarily a great hassle when comparing it to the Native test frameworks on iOS and Android.
We did not implement the entire project as we did natively owing to the time frame and the further complications and challenges that we faced as we continued in the project. Below are some of the main challenges that we faced:
- As part of getting familiar with a new platform, any developer refers foremost to the documentation and resources for this platform. For React Native this was not the case, even though Facebook keeps it’s documentation up-to-date but we found that most components are not well documented and can be at times confusing.
- Compare React Native’s documentation with that of the native development, Apple and Google cover every detail sufficiently and easily for developers.
React Native Components
- React Native components do not include essential components used for mobile development, for instance navigation bar. So why re-invent the wheel? Why start with the smallest component, instead of providing ready-made components?
- Most components are still work-in-progress, although they are released, they are in fact still in development or have been replaced with other components. For instance when we used the now deprecated ListViews replaced it with SectionLists, and despite that, it was still possible to scroll faster than the fill rate and momentarily see blank content.
- Key features like navigation are not clear what is recommended. Facebook suggested three libraries for navigation, native-navigation by Airbnb, react-navigation by Facebook and the community and react-native-navigation by wix.com, of which we tried react-navigation and react-native navigation. We found that both have intermittent drawbacks. Additionally, using react-navigation’s custom navigator to provide our custom navigation was very complex due to insufficient documentation.
- There is a shortage in third-party libraries compared with those provided on native platforms by the community.
- The libraries behaviour varies from Android and iOS — most libraries do not provides custom behaviour that is consistent for both platforms.
- If we were lucky and found the library we needed, we may get a version compatibility problem. For instance they were only compatible with older React Native versions and do not support the latest version.
- Additionally, owing to the many libraries/packages in our project, package dependency conflicts arose with every npm install, which is a big obstacle for large scale projects.
- Third-party library linking in React Native to the iOS and Android projects was not always successful, which can be problematic for those without experience in adding libraries/modules in Xcode and Android Studio.
- In our native iOS project, we used 7 libraries, and in Android we used 9 libraries whilst in React Native we used 27 excluding the React Native core packages. Also due to the many project libraries we used in React Native, the Android project would not run and dexOptions had to be enabled.
- Touch events were not smooth like that of our native app, there were at times delays in touch event capturing, so we would assume that the touch event was not captured and tap twice.
- Gestures were not smooth, for instance, we tried several libraries to get a swipe-to-delete smooth effect but it was still noticeably different than that of native.
- Keyboard customizations was not possible as in Native.
Integration with Existing Code Base
- Integration with existing classes that used fragments and activities (Android) or view controllers (iOS) was not possible unless they were changed to views.
- In Android changing the code to remove fragments and activities was simpler than in iOS to remove view controllers due to the bridging from Swift to Objective C and the bridge from Objective C to React Native.
- No preview for UI, live reload overcomes this, but it does not apply only for UI but for every single code change. Although live reload is impressive, it can be annoying, so most of us opted out from using it.
- Nuclide, the official React Native plugin for Atom by Facebook which includes autocomplete and code diagonistics was not sufficient when comparing it to Xcode and Android Studio, thus the switch to VSCode.
Debugging and Crash Analysis
- Debugging was very slow on device, specifically on Android devices and occasionally on iPhones.
- The development server would sometimes return response error code 500 and the issue would resolve by simply reloading the app.
- Linking multiple times may result in the addition of dependencies twice to the Android project.
- While downloading packages, some packages may fail to download their dependancies which resulted in corrupted node modules. And since there was no existing viable solution for this, we resorted to copying the node modules from other team members.
- New types of errors arose with more package installations without useful and relevant information.
Is the Praise of React Native Around the Web Really Justified?
We realized, provided that we had previous knowledge of ES6 and React, project progress would have been faster. It would have helped us enhance the code, understand the component lifecycle methods better and apply more best practices that avoid unnecessary renders and long render times of components.
So, from this perspective, we can conclude, React Native is more suited for Web engineers switching to mobile development without learning native languages. Thus, React Native’s principle of learn once run anywhere.
Is the Development Time Using React Native Reduced Significantly?
During the development of our application for iOS and Android natively, there were six developers working with a total of 950 hours spent within seven weeks to complete the complete scope. Implementing the project using React Native took a total of 11 weeks development, 780 hours with 4 developers for around 70% scope completion. The look and feel of our app did look like a native app, and for the most part with some adjustments to the specifications provided in the Zeplin design, we had a similar-looking app. Although there was a noticeable difference in performance.
This myth is definitely busted! You might be able to develop an app for two platforms with smaller efforts if you intend to to make concessions to usability and visual appearance. But if your intention is to make a cutting edge app, then you’re ending up spending plenty of time fixing small issues and optimising the look and feel on each platform.
Does React Native Truly Fulfill the Needs of Clients?
Facebook pushes new updates every month, as a result, many packages/modules break due to this constant change. Compare this to the stable changes released by Apple and Google yearly. So, for a long maintenance and complex project, using React Native is not a reliable option as it is not mature and stable. In addition, due to this instability and unpredictability of the different types of errors, project time estimation will not be accurate.
React Native was a great learning experience for us. Overall we feel that React Native is at junction to a path that will lead to either a stable and promising future or will continue to be unstable and the choice for short-term projects only.
Credits: Modeso’s Mobile Engineers Olla Ashour, Esraa Yasser, Shimaa Ibrahim & Rania Elmansy.