React Native ~ Application Architecture - rohit120582sharma/Documentation GitHub Wiki

UI Components

React Native is like React, but it uses native components instead of web components as building blocks. So to understand the basic structure of a React Native app, you need to understand some of the basic React concepts, like JSX, components, state, and props.

  • props - any data that is passed to a component as part of it’s creation is classed as props. The data flows from the top downwards, ie. from parent to child. If a parent passes new props to an existing child this will trigger the child to re-render. The props are saved for reference throughout the life of the component but the component itself does not have the power to change them.
  • state - any data that a component decides to store within itself is it’s state. State is the sanctuary over which a component can retain complete control. Every time a component’s setState() function is called, it performs the dual actions of both updating the state, and re-rendering the component.

React Native provides a number of built-in components to create views. React Native application does not depend on HTML or CSS and is written in JavaScript, but this JavaScript is compiled to platform-specific Native code using the React Native bridge. It happens all the time, but it is optimised in a way that the application will run smoothly in 60 fps.

We are also using following libraries:



Styling with Flexbox

React Native uses the Yoga library under the hood to drive layout. Yoga is a C implementation of Flexbox and it includes bindings for Swift, Objective-C, Java (for Android), and C# (for .NET).

Generally you use a combination of flexDirection, alignItems, and justifyContent Yoga properties to manage your layout.



State-management

Redux is a great pattern for centralising state management with immutable data structures. This concept is called "Single Source of Truth". Let us understand each area of this architecture:

React-Native Views

React Native follows component architecture for UI construction same like React. React-Native views makes a request based on interactions on/with the application. A React-Native component can contain local state, but we avoid this. A functional (stateless) React-Native component will always render the same UI given the same props. By keeping the state in Redux, we can always produce the same UI state given the same store contents.

To connect the store to the views, we first have to pass store and Provider component as parameters when registering components as screen for navigation. Then we can connect our components to store using connect().

Store and Immutable.js

Store is a single object that holds the complete state of your application. It delegates the reducer with the responsibility of changing state when an action is dispatched. We use Redux which is a library that controls the state of our application. It provides a “unidirectional data flow” that helps to manage and organise data better and makes debugging a lot easier.

We're also using "immutable.js" which is efficient data structure library providing immutable Lists, Maps and more. It relies on structural sharing to reduce memory footprint while staying immutable. It's cheap to determine if a component needs to re-render because Immutable data structures cannot be mutated.

Saga

It is a Redux middleware for handling async operations like fetching data from Fusion Production APIs. It makes asynchronous operations look like standard Javascript synchronous code making it easy to read, test, and reason.

Action handlers

It is commonly called action creator which returns a formatted object of the action type and optional payload. They are passed via the Middlewares to the Reducers.

Reducers

They are simply pure functions whose purpose in life is to accept the state tree and an action from the store; make a copy of the previous state, transform it and then return a new state to the store.

Selectors

We are using Reselect library for creating memoized, composable selector functions. Reselect provides a function createSelector for creating memoized selectors.

We use selectors to:

  • Selectors can compute derived data, allowing Redux to store the minimal possible state.
  • Selectors are efficient. A selector is not recomputed unless one of its arguments changes.
  • Selectors are compassable. They can be used as input to other selectors.


Networking

Many mobile apps need to load resources from a remote URL. You may want to make a POST request to a REST API, or you may simply need to fetch a chunk of static content from another server.

By default, iOS will block any request that is not encrypted using SSL. If you need to fetch from a cleartext URL (one that begins with http) you will first need to add an App Transport Security exception.



Navigation

We are using react-native-navigation library which provides 100% native platform navigation on both iOS and Android for React Native apps and has an easy to use Javascript API. React Native Navigation comes with optional redux support out of the box.

Navigation includes the entire skeleton of your app with critical components like nav bars, tab bars and side menu drawers.



Debugging

React Native allows you to debug your code by using the console.log() method, which should already be familiar. Aside from console logging, there are some other debugging tools such as React Native debugger, which should really come-in handy.



Testing

We are using Jest (Read about it here) because:

  • We wanted some framework which could be easily setup and start testing. i.e spend minimum time to setup the framework for our project.
  • Ability to run tests in parallel. For a huge app like us with lot of tests, it will be quick if the tests could run in parallel.
  • Snapshot testing. This is a really cool feature which helps to reduce number of tests we have to write as we just create a snapshot and if anything changes in our components, we will get an error when the snapshot is generated the next time.
  • Jest uses Jasmine for assertion which is easy to write tests.
  • Code coverage is available right out of the box and it can be integrated as a part of CI/CD pipeline by simply passing required jest coverage parameter.
  • In-built Manual mocking
  • Awesome interactive watch mode that reruns only tests that are relevant to your changes.
  • Helpful fail messages.
  • Simple configuration.


Bundling

Metro is a JavaScript bundler for React-Native. It takes in options, an entry file, and gives you a JavaScript file including all JavaScript files back.

Metro has three separate stages in its bundling process:

  • Resolution - Metro needs to build a graph of all the modules that are required from the entry point. To find which file is required from another file Metro uses a resolver. In reality this stage happens in parallel with the transformation stage.
  • Transformation - All modules go through a transformer. A transformer is responsible for converting (transpiling) a module to a format that is understandable by the target platform (eg. React Native). Transformation of modules happens in parallel based on the amount of cores that you have.
  • Serialization - As soon as all the modules have been transformed they will be serialized. A serializer combines the modules to generate one or multiple bundles. A bundle is literally a bundle of modules combined into a single JavaScript file.
⚠️ **GitHub.com Fallback** ⚠️