React Native

Author Mileta Dulovic
Author

Mileta Dulovic

What is React Native

React Native is an open source framework for building Android and iOS applications using React and the app platform’s native capabilities. With React Native, you use JavaScript to access your platform’s APIs as well as to describe the appearance and behavior of your UI using React components.

React and React Native

React Native hase similar API as React. React functional components, hooks, hoc, state are all same in React Native, and if you worked with React, it won't be an issue to learn React Native.

Key differences are that React is for Web, and React Native for mobile development (you can also do web with React Native, but we won't talk about that in this post). With React Native you need to think differently because you are not developing for the web anymore. You don't have :hover on elements, you don't have media-query (at least not natively).

You need to think about routing differently, because you are not dealing with web pages anymore, but with mobile screens.

Styling

Styling in React Native is done via StyleSheet API (by default), but you can also use styling libraries like styled-components.

StyleSheet is basically a JavaScript object that has some properties. It is that same as if you'd want to inline a style in React.

const style = StyleSheet.create({
  container: {
    width: '100%',
    height: '100%',
    backgroundColor: '#000'
  },
  title: {
    fontSize: '24px',
    color: '#fff'
  }
})

// Adding styles to elements
<View style={style.container}>
  <Text style={style.title}>Title</Text>
</View>

Styles are written using camelCase and assigned to elements by selecting property from an object and adding it to style prop of an element.

Performance

Performance is something that concerns everyone when it comes to cross-platform frameworks.

React Native has great performance. Let me elaborate.

React Native used bridges to communicate between Native threads and JavaScript. All data had to be serialized as JSON and sent over the bridge, and then it had to be decoded on the other side. This meant that JS couldn't call Native thread directly, which created some problems when it comes to performance.

By default, it was all asynchronous, which was good in most cases, except in those where JS and native code had to be in sync.

JSI

Recently (v0.68) React Native team announced release of a new architecture. JSI (JavaScript Interface) replaces old bridge system.

JSI is lightweight layer written in C++ that can be used by JavaScript to call Native thread directly. This means that there is no more middle-man (bridge) between JavaScript and Native, which in return increased performance by a lot.

Fabric

Fabric is new rendering system which replaced old UI Manager.

With JSI, native methods are directly exposed to JavaScript, which includes UI methods too. With this JS and UI will be in sync, which in return will improve performance for gestures, navigations, long lists etc.

With new engine users interactions will have priority and will be executed synchronously in the main thread (or native thread). Other, less significant tasks, will be executed asynchronously without blocking main thread, and app will feel much more responsive to user.

App size

When it comes to React Native apps, they are pretty small.

There are a lot of options to enable that will help in reducing app size, both install and on device.

Best way to reduce app size is to enable enableSeparateBuildPerCPUArchitecture. This will create apk for each architecture when you upload it to store, and user will automatically download only one apk type that will work for his device. This means that less code will be bundled in the apk, and size will be much lower.

You can also enable proguard. Proguard is a tool that can slightly reduce the size of the APK. It does this by stripping parts of the React Native Java bytecode (and its dependencies) that your app is not using.

Animations

Animations in React Native are pretty easy once you understand how they work.

Consider this example for opacity animation

import React, { useRef, useEffect } from 'react';
import { Animated, Text, View } from 'react-native';
const FadeInView = (props) => {

  // Initial value for opacity: 0
  const fadeAnim = useRef(new Animated.Value(0)).current

  // useEffect to animate opacity
  useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
    }).start();
  }, [fadeAnim])

  // Special animatable View
  return (
    <Animated.View
      style={{
        ...props.style,
        opacity: fadeAnim,         // Binding opacity
      }}
    >
      {props.children}
    </Animated.View>
  );
}

// You can then use your `FadeInView` in components:
export default () => {
  return (
    <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
      <FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
        <Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
      </FadeInView>
    </View>
  )
}

Animation Breakdown

First we create special variable using useRef to save variable's value during re-renders.

Animated.Value(0) tells the variable that it's value will change in future using Animated API, and that initial value is 0

const fadeAnim = useRef(new Animated.Value(0)).current

Main part of the animation is inside useEffect

useEffect(() => {
  Animated.timing(fadeAnim, {
    toValue: 1,
  }).start();
}, [fadeAnim])

Here we are configuring animation using React Native's Animated API, and we tell that we should animate fadeAnim variable to the 1 when component mounts.

We then pass that variable to the Animated.View for the animation

<Animated.View
  style={{
    ...props.style,
    opacity: fadeAnim,         // Bind opacity to animated value
  }}
>
  {props.children}
</Animated.View>

There you have it. Simple fade in animation with React Native.

You can also use libraries to handle animations even simpler (like reanimated) but I like to keep things without libraries, unless code readability suffers, or complexity is too high for me to handle.

Conclusion

Many will hate React Native, and many will love it. I am in the second group. Working with React Native has been a breeze, and it just gets better. Can't wait to see what future holds.