Back to the blog

Why and Why not React Native

author image

Abhilash Behera

Technology | July 30, 2019

hero image


You would have already come across similar blogs where people explain or try to explain the pros and cons of react-native. In this blog, I will try to go deeper into the development side so that you actually understand what are the boosters and hurdles when you decide to develop or get your application developed with react native. So let’s start.

Hello there, welcome to my very first blog. Most of you have probably landed here because you wanted to know the pros and cons of react-native to answer interview questions or maybe you came up with a new business idea and you want to get it implemented on the right platform, maybe you are a smart developer who wants to prove his point on React-Native in an argument with other friendly developers, or maybe you are a very clever freelancer who is searching for the right platform to suggest to the client before starting the project. No matter what your intentions are but the main goal is to decide why or why not you should use react native for your applications.

Why React Native

React native is a very popular solution created by Facebook for cross-platform mobile app development. There are already many cross-platform solutions but React Native is popular because it uses our favorite Javascript as the development language. There was a time when web development and mobile app development required separate skill sets. But with react native any web developer who has knowledge of javascript can start developing mobile applications. So companies have to basically hire a developer with strong javascript knowledge and he can develop web applications as well as mobile applications.

Requires fewer resources and efforts

As I already mentioned in the previous point companies have to spend fewer resources for getting an application developed for both ios and android. If you are developing an app for all the three platforms ( Web, iOS and android ) and you want to go with Native apps then you will have a separate development team for web, iOS and Android. Moreover, if you want all of the apps development process to be parallel then you will have separate testers for all three platforms. So using react native the same javascript guy can write code for web and react native which will run on both iOS and Android.

A single codebase for android and ios

If we are using react-native we write all of the code in javascript. This single codebase makes our app run and looks exactly the same on iOS and Android. So this is a big advantage when it comes to fixing bugs and implementing new features in the app.

Whatever improvement it is you just add the code to the same javascript codebase and the changes are reflected both in iOS and Android, unlike native development where you will have to implement the changes both in iOS app and Android app separately. So React Native obviously saves your resources in this use case.

The app performs like a native app

Unlike hybrid app development platforms like Cordova which uses a web view to load the HTML pages and gives you a feel of the native app, React Native actually uses native components under the hood. For example, if you are using a Text component in react native, in the android app it is automatically converted to the native TextView component of android. So if you use react native to develop your applications, your app not only looks native but it actually has the native components like any other native app.

Huge community support

React Native has huge community support as it uses Javascript which again itself has huge community support. So if you are working with React Native and you find yourself surrounded with bugs then React Native Community is there to your rescue. The community is very active, so your problems and queries are responded at the earliest.

Following are the react-native communities which are ready to help you anytime with your queries or problems with development

Best for startups

Most of you are already familiar with a startup environment where to get an idea implemented the timeline seems to be very short maybe due to a shortage of resources or developers, maybe due to already existing competitors whom you are trying to beat or maybe sometimes the timeline is actually short. So in these cases, you prefer React-Native as it requires fewer resources and development time.

Easy to get started

Yes, React Native is easy to get started if you know Javascript. And it’s super easy to get started if you know React JS. Since Javascript is the most common programming language nowadays, therefore, React-Native is easy for most of the developers out there. New developers fall into trouble and bugs very often so the huge community gives them a benefit over any other technology. So if you already know Javascript and you want to learn React Native then you can dive into it now.

Hot reload and Live reload

The best part, React Native supports Hot reload and Live reload. It is a very good system where you are able to see your changes live without having to re-run or reload the app. Hot reloading is a feature that reflects your changes in maintaining the app’s current state. This means if you are on a particular page, having the Hot reload feature enabled and doing some changes get reflected on the same page without starting the app from the beginning. Live reload is a feature where the app is automatically started from the beginning with the changes reflected without you having to reload.

Why Not React Native

Ok, folks so finally we are here. Let’s meet the bitter part of React Native. Let’s see what are the hurdles which are going to come on your development track.

Performance

This is the most heard, the most popular and the most important point in the bitter side of React Native. Yes React Native has serious performance issues. It would be better to list down the performance issues:-

  • The more tabs, navigations, controls, animations, third-party libraries your app has, the slower React Native becomes.
  • Has memory leak issues in android when you use ListView.
  • App size increases heavily on using third-party libraries. Obviously, you have to use them because you want your app to be developed faster and also you cannot create or develop everything from scratch in a given time frame.
  • Delay in updating UI in android. React native offloads all complex functions to the Javascript thread which causes a delay in updating the app’s user interface. And when that happens, the app stops responding to user inputs and performance lags are extremely apparent. The same offloading can drastically impact animations from executing. The main javascript thread if isn’t free, navigation and layout related animations won’t launch
  • This is a recent problem where we were working on an app in our company. We had the audio files and image files encrypted with the AES algorithm. When the user goes to a particular page we had to decrypt all the images and decrypt an audio file when the user selects audio to play. So when we wrote the Image Decryption code in react-native, for decrypting 150 images the app took around 7-8 seconds. And when the user clicked on a single audio file of around 5 mins duration the app took around 10 seconds to decrypt the audio file. During this duration, we had to show the loader. Everything seems to be good from a developer’s point of view. But when the app is actually launched and it reaches the user, the major question in the user’s mind is “ Why is it taking so much time to play the audio or display the images even when all of the content is present in my local storage?”. And the next thing they do is uninstall the app because of frustration. So we had to build a React-Native native bridge to fix the problem. I have written a separate blog regarding this.

Startup Time

Yes, React Native has a startup time issue when your application is complex ( almost all of your applications are complex unless you are building a “Hello World App”). The reason behind the startup delay is the JS bundle. Whatever code you write in React Native is compiled and bundled into a JS bundle which the app loads at the startup. This JS bundle holds your app’s logic. So the more third-party libraries you use ( you actually have to use lots of third-party libraries when working with React Native ) the more is the size of JS bundle and the more time the app takes to startup.

Increased APK size

If you are working with React Native instead of real native apps then your APK size is going to increase drastically. For a simple “Hello World” application React Native shows a huge increase in the APK size. Follow this link which gives a very detailed and clear picture of this problem.

Migration to AndroidX

If you have ever worked with android apps then you might know that android has recently launched AndroidX which is a development tool and a set of libraries that simplify many problems of an android developer. So if you go the android docs you will find the steps where you add 2 parameters named android.userAndroidx and android.enableJetifier and the rest of the things are taken care of by Android Studio. When these flags are used, android studio finds and replaces the old support library imports with AndroidX support library imports. But this is not the case when your android app is built with React Native. Even after using the above parameters android studio will be unable to find the old support library imports used inside the react-native libraries. Let’s take an example of the react-native-camera. It uses the old support library. But when you add the AndroidX migration flags in Android Studio it will not replace the dependencies and imports of the react-native-camera library. This will lead to a crash and sometimes you cannot even build the APK file. I have written a blog to deal with this problem here

Difficult for automated testing

Have your QA ever complained about having difficulty in testing your app developed in React Native? Yes, It happens. If you have used Appium for testing apps then you might know that it requires to access the Views or the Elements to perform operations on them. For this to happen we need some sort of unique id for the elements so that the appium server can access them. If you develop an application in android then you already give a unique id for the important elements for their positioning relative to others or for having reference to them in the logic. In Android, this is done like this android:id=“@+id/uniqueId”. So the appium server can easily access this element. But when you are using ReactNative this is not the case. When testing React Native apps, a unique ID might be exposed for iOS but not for Android.

Unless the app is changed, this can make it extremely hard for testers to uniquely identify specific objects. See this link. Obviously, there are workarounds. But I personally believe in a perfect and permanent solution not “Workarounds”.

Difficult animations

Animations are difficult and complex when you are working with React Native. I will explain this through an example:

class FadeInView extends React.Component {  
      state = {  
              fadeAnim: new Animated.Value(0),  // Initial value for opacity: 0  
              }  
    componentDidMount() {   
    Animated.timing(                  // Animate over time        
    this.state.fadeAnim,            // The animated value to drive  
          {  
             toValue: 1,                   // Animate to opacity: 1 (opaque)  
             duration: 10000,              // Make it take a while  
         }  
        ).start();                        // Starts the animation  
  }  
    render() {  
            let { fadeAnim } = this.state;  
                return (  
                        <Animated.View                  // Special animatable View  
                        style={{   
                                …this.props.style,  
                                opacity: fadeAnim,         // Bind opacity to animated value  
                                        }}
    >
 {this.props.children}  
       </  Animated.View  >  
           );
             }
             }

This code is taken from the React Native official site (it’s not mine 😉 ). So you have to write these many lines just to implement a simple fade-in animation. Let’s see what you have to write in android if you want this animation

Private void startAnimation(View v){  
 AlphaAnimation alphaAnimation = new AlphaAnimation(0f, 1f);  
 alphaAnimation.setDuration(10000);  
 v.startAnimation(alphaAnimation);  
 }  

Yes, that’s it. It’s true. Native animations are very easy and very nice to see.

Difficult to customize libraries

When you are working on React Native and you are building a complex app, believe me, you are going to need a lot of third-party libraries unless you are ready to redesign the wheel or ready to develop everything from scratch and spend a couple of years for making your app. So when you have chosen a third-party library and started implementing it, at some point in time, you are not happy with what the library actually provides in spite of being the best you have chosen from the hundreds out there. Or let’s say you find a simple issue with the library but you do not want to switch to some other library. In this case, you will have to report the issue to the developers of the library and wait until they fix it. Seems a feasible solution? No. It’s not feasible. You are bound to timelines when you are developing applications. So you cannot wait until it is fixed. In our company, we were developing an application where we needed a snackbar. So we choose react-native-snackbar. But after implementing it we found out that whatever message we sent to the snackbar, it displayed only a single line and hide the rest. So we had to report to the developers. They marked it as a feature request and fixed it in 5 days.

Conflict with dependencies of internal libraries

When you are developing complex applications you also import some libraries like firebase-authentication, firebase-analytics, etc. For some libraries like these, you have to also import the latest android support libraries. But the problem occurs when some of your react-native libraries also need support libraries but a different version of it. In this case, the android studio runs into conflict while merging the manifests or resources. Again to solve this issue there are lots of workarounds. But remember these are just workarounds. If you tweak something in the react-native libraries’ internal files and you are working collaboratively then the other guy in your team working on the same project will not be able to receive those changes as your changes are inside the node_modules folder.

Complex storage library ( REDUX )

Believe me, the most popular storage library redux is complex. You must be intelligent in how you write the reducers and actions to be dispatched to ensure immutability, and the state can (with even a small application) quickly grow difficult to maintain. For using redux in your application you have to add a lot of boilerplate code (views, action types, action creators, reducers, selectors). Redux does not have an out-of-the-box solution for dealing with side-effects (available through middlewares such as redux-thunk or redux-saga)

Separate styling for android and ios

To get a clear idea of this, let’s look at some screenshots

!

!

The screenshot on the left is from iPhone X and the one on right is from an android device (Oppo F11 pro). I hope you can notice the difference between the height of the text input field. Now let’s look at the react native code.

const App = () => {
    return (
         <View style={{backgroundColor:”#ffffff”,justifyContent:’center’,alignItems:’center’,height:’100%’,width:’100%’}}>
         <Text>Hey There</Text>
         <TextInput  placeholder=”Type something here” style={styles.textInput}></TextInput>
        </View>
    );
    };
const styles=StyleSheet.create({
          textInput:{
         backgroundColor:”#efefef”,
         borderColor:”rgba(0,100,200,0.5)”,
         borderWidth:2,
         borderRadius:10,
         padding:10, 
         fontSize:16,
         letterSpacing:6,
         width:’90%’
  }
 })

Look at the textInput style at the bottom. This is the same for iOS and Android which you just saw in the screenshot. Now to solve the style issue we have to use Platform.OS from. Let’s look at the modified style code and then at the new screenshots.

const styles=StyleSheet.create({
      textInput:{
              backgroundColor:”#efefef”,
              borderColor:”rgba(0,100,200,0.5)”,  
              borderWidth:2, 
              borderRadius:10, 
              //padding:10, //We have to make padding platform specific to fix the height issue  
              fontSize:16,  
              letterSpacing:6,  
              width:’90%’, 


                 // Platform Specific style code starts here
                    …Platform.select({
                    ios:{
                            padding:18  // Padding for ios
                        },   
                    android:{  
                            padding:10  // Padding for android     
                            }            
                           })  
                             }
                             })

!

!

So we have made the style platform-specific. Let’s look at the screenshots.

So this is what you have to deal with most of the time when you are developing an application in react native.

Library implementations need native effort

Implementing libraries like Firebase Analytics, Firebase Auth, Crashlytics, Google Maps, Push Notifications, Geo-Fencing, etc. require you to do some configurations and code on the native side also. By the term “Native Side” I mean you have to get into your ios or android project generated by React Native and do the configurations in the mentioned files. So to make a good application you will obviously implement these libraries or tools. So if you are a beginner in React Native then this is going to trouble you and cost you late nights. Moreover sometimes, the library implementations on the native side cause some errors which you will have to fix on the native side itself. Of course the libraries docs clearly mention the steps on how to configure it on the native side, but believe me, the implementation does not work the first time unless you are a “Pixel Perfect Developer”. This problem gets tougher when you have zero knowledge on the native side. So the point to remember here is, if you are developing a complex application then knowledge of only React Native is not going to help you. You should also have basic knowledge on ios and android.

Platform-specific library limitations

Now, this is a very pathetic problem. Some of the React Native libraries and third-party libraries have platform-specific limitations. Let’s take an example.

!

When you are working with React Native app your view covers full screen irrespective of the notch. So this is where SafeAreaView comes into the picture. But the problem is this SafeAreaView is only supported for iOS and not Android. Follow this link to see how people have suffered from this. The same goes for React Native ScrollView. Check this link to see how some of the properties are only supported for a specific platform.

Image caching not supported for both platforms

I hope you got this one. Yes, Image caching is only supported in iOS. This is a very important feature that improves User Experience. To implement Image Caching in both iOS and Android you will have to use third-party libraries which will again add some KBs to your JS bundle.

No Direct support for SVG

If you ask to google “how to optimize your application or webpage?”, most of the results will definitely mention the usage of SVGs instead of multiple resolution-specific copies of your resources that will reduce your asset size. But the problem is you cannot directly use SVG files in React-Native. Because it simply just does not understand what it is. To make it understand what it is you will have to create an SVG Component with the properties of the SVG which is obviously not a interesting thing to do unless you are fond of writing SVG code. So you will end up with this

!

!

The image on the left shows the contents of the actual SVG file and on the right shows the React Native SVG Component for the same SVG.

You have to copy the generated output from the site and make a new Component, paste it into the component, import it and use it. But imagine when you have to use 40 SVGs. Are you still ready and happy to repeat this process 40 times? If yes then I am your fan 😉

Ok, that’s it for this blog. These were the pros and cons I faced when building an application with React Native. The issues reported here may not be permanent. The React Native Community is already and always working hard to fix the issues. These issues may be solved with some awesome new releases. I hope this blog was helpful to you. Thanks for reading.

Browse all categories