Delightree: A Cross-Platform Mobile App

Himanshu Tiwari
The Official Blog of Delightree
5 min readMay 17, 2020

Going noob to pro in building a hybrid react-native app

A snapshot of the delightree app
A snapshot of the Delightree app

The Objective

Delightree is a workflow solution enhancing the efficiency of remote teams, especially franchise businesses. The idea is to reduce all the clutter when it comes to cross-team conversations and provide a single source of truth.

It can be used to measure the productivity of an employee, a department, a location, or even the business as a whole.

A manager can create general announcements for everyone or a specific team/individual. Similarly, there can be tasks to alleviate certain issues divided into sub-tasks for various personnel.
They can also create repetitive processes to make sure a smooth flow of standard procedures.

React Native (Our Swiss Army Knife)

React Native is the go-to platform these days when a product team decides to move their application from the web to native.

React Native combines the best parts of native development with React, a best-in-class JavaScript library for building user interfaces.

If you have a team with experience in building web apps with React Js, choosing a hybrid platform like React Native reduces a considerable amount of time needed to scale the learning curve.

Level 0: Setting Stuff Up

Just like any other project, the Delightree app also requires a bit of boilerplate code. However, there is an extra effort required to set up XCode and Android Studio. The latter is easy enough to figure out, but it can take us a while to get familiar with the former.

We begin with a basic auto-generated developer certificate from XCode and setup hot reload and on-device debugging with the help of React Native Debugger.

Level 1: Authentication and screen navigation

Authentication generally delays the lift-off time for most of the apps. Hence, we are choosing to go with Auth0. It provides ready to use authentication and authorization APIs coupled with a responsive UI. We just need to install the package and write minimal code to achieve our goal.

The next thing is to build routing, also called screen navigation in the native apps ecosystem. This time we use the latest version of React Navigation.

We have already worked with routing in React Js projects but it’s not the same thing here. For example, components once mounted will not be unmounted once we move to other routes. Also, the positioning of the navbar is mostly out of our control.

Bonus Level: React Hooks and Context API

Before this project, stateful components always meant class components for us. This time however we have decided to use functional components all over and utilizing pre-defined as well as custom hooks.

This means a loss of various lifecycle methods and a change of thought process, moving all such code into the useEffect hook and creating state variables using the useState hook.

We are also starting to consume the context API to share common variables like the current user’s details and in-app notifications. The useContext hook will be used to access this data in the functional components.

Level 2: Basic functionality and UI

Every project has a few aspects that require minimal effort. Building a pixel perfect and responsive UI is one such aspect. It can start with us defining the major components and just filling up the screen with the required data. Next, we add the styling and animations to provide an optimal user experience.
This is the easiest part of the project for us, given our experience in the field.

Level 3: Apollo Client

Since we have already chosen most of the leading-edge tech, we decide to go for GraphQl as the query language to access the backend APIs. Going a step further, Apollo seems to be a sensible choice for a state management library.

With Apollo, all our queries will be cached automatically and we won’t have to worry about adding something like Redux to the product. Along with queries and mutations, Apollo also provides a third type of operation called subscriptions, which can be used to keep the frontend cache updated at all times.

To our benefit, we can also use hooks like useQuery, useMutation, and useSubscription to utilize these. There is a special hook named useLazyQuery too, to make a query when we want, rather than at the time the hook is encountered.

The default cache-first fetch policy of the apollo client decreases the request time as well as the number of network requests.

Level 4: Push Notifications and Hardware Access

Sending push notifications is the most popular way of user-reengagement these days. Even more so for a task management app. Hence, we choose OneSignal, a leading service provider in the market.

Setting up notifications for iOS is going to be a pain though. It involves creating various keys and certificates, enabling capabilities, etc. We have never dealt with these things for native apps. So, we take a bit of help and guidance from the developer community and make it possible through sheer persistence and a lack of proper documentation.

Mostly, the reason to switch from web to native is the ability to better access the hardware. That seems to be true for our case as well. Our requirements involved a basic usage of the camera and file storage. This is going to be way easier with React Native than with the React Js PWA we had to build earlier (*thanks to the Safari Webkit team*).

Boss Level: The Optimization Ordeal

Until now, we were making use of the latest tech and building stuff exactly as per the requirements. Except for one thing. SPEED.

As the app starts to grow, it also starts getting bogged down with app freezes and loaders. The amazing features we discussed above that make these technologies great, now look like the biggest hurdles when combined.

For example, React Native Navigation does not unmount components on moving to other routes and once an Apollo subscription is received, the associated component and all its children get re-rendered. In essence, that means a component with a large list can re-render in the background resulting in an app freeze and you wouldn’t know what exactly happened.
A quick solution is to skip the subscription if the screen is not focused.

Arrow functions are also highly used in modern React apps. For all their benefits mentioned all over the internet, when passed directly to a component, they can decrease the performance by getting re-initialized on every re-render.

The naive solution would be just moving the function out of the component. However, that is not possible every time. In such cases, hooks like useCallback come in handy.
While this can seem like a minor update, for a large React Native app, it can result in a considerable performance boost.

Game Point: Deploy and Distribute

Finally, it is time to create the production builds and deploy to the App Store for iOS and the Google Play Store for Android. Once again, the iOS submission can turn out to be a headache. We need to create separate certificates and keys for app distribution and add the required capabilities to the same. The apps will be reviewed and the beta versions will be available on the following links:
https://play.google.com/store/apps/details?id=com.delightree
https://apps.apple.com/us/app/delightree/id1505988671?ls=1

GAME OVER

See you in the next one!

--

--