Electrode Native Navigation

Deepu Eswarath G
Walmart Global Tech Blog
8 min readNov 13, 2019

Today’s mobile-technology climate brings myriad development platforms upon which applications can be built, each with its own advantages and disadvantages. React Native is still a relative newcomer to the field, which brings its own set of challenges. The Electrode Native platform was released in 2017 to assist in overcoming these challenges, allowing a more seamless integration of native and React Native applications.

During development of the Electrode Native platform, a major concern has always been centered around the support of navigation across the entirety of an application; whether the content of any given page was written in a native language, developed using React Native, or a combination of the two.

Given the flexibility and complexity of applications that can be created with React Native, there are many different use-cases for navigation which need to be accounted for, including:

  1. An integrated React Native application launching a native portion of the application.
  2. Native code launching an integrated React Native application — at Walmart we have many applications that were initially developed to be fully native, which now wish to incorporate new React Native features.
  3. One React Native application navigating to a page in another React Native application. Electrode Native was built around the concept of multiple disparate React Native applications inside of a parent native application, so this has always been an integral requirement.
  4. The ability to perform A/B testing in such a way that features could be compared between their React Native and native versions. Any company like Walmart must ensure that it performs proper A/B testing before releasing any new features, always thinking of the customers’ needs first and foremost.

To address these concerns, we have developed Electrode Native Navigation (ern-navigation), a new navigation framework from the Electrode Native team.

Introduction

Navigation is a core feature of any application; both Google and Apple continue to invest great amounts of effort to streamline their native navigation architecture. The main goal of this project was to empower React Native application developers with the ability to navigate using native components and principles. By doing so, we are able to create reusable, native-friendly pages and applications.

During the development of Electrode Native Navigation, we focused on these core principles:

  1. We must eliminate the need for a React Native application to maintain its back-stack, and leverage all of the features which are offered by the native framework in managing the navigation queue.
  2. We must ensure that all transitions between pages and applications use the same animations, whether those pages are built using the native or React Native architecture.
  3. We must allow for custom layouts — this includes layouts with mixed native and React Native content.
  4. We must use the native navigation bar managed entirely on the React Native side (this is helpful for existing applications looking to include React Native components inside of their native application).
  5. We must have the same navigation implementation whether running inside of a standalone React Native application or as part of an integrated native application.

What is Electrode Native?

Before we jump into Electrode Native Navigation, it’s essential to understand what Electrode Native is, and why we have created this framework. Electrode Native allows for the combination of multiple MiniApps (React Native applications) into a single container. The container is generated entirely by the Electrode Native platform and is packaged as an AAR library for Android and as a Framework for iOS (these libraries are similar to standard third-party libraries that Android and iOS developers are familiar with).

Why did we not use one of the existing React Native navigation frameworks?

There are many React Native navigation frameworks to choose from that provide excellent navigation support inside of a single React Native application which requires minimal native integration. Electrode Native Navigation was developed mainly to support:

  1. A hybrid approach to application development, where multiple MiniApps are built into a library and are integrated with a larger, native application.
  2. A single React Native application with multiple pages — without an existing native application — which needs a navigation framework.
  3. An application architecture which allows native and React Native pages to coexist, enabling both native and React Native developers to contribute during an application’s development lifecycle.

Electrode Native Navigation

Electrode Native Navigation (ern-navigation) follows the core principles of mobile navigation. Any flow always has a starting page (its root) and an ending page where a user completes the flow, moving back to that flow’s root. Consider the following example of our MovieApp developed in React Native using Electrode Native Navigation

Here, the user starts with the Movie List page (its root). Clicking on the details button for any movie takes the user to a Movie Details page, with more detail about the movie. From there, the user can then navigate to the Cast List page for a more extensive list of the cast who took part in the selected movie.

MoviesReloaded app navigation

In a typical React Native application, we register the root component; this allows a native Activity (Android) / ViewController (iOS) to load this component when it is launched. From there, the responsibility for navigation is handed over to the React Native application. Doing so separates the native application from the user flow.

Let’s take the simple example of our MovieApp above and dive into how Electrode Native Navigation works behind the scenes.

React Native

With Electrode Native Navigation, we register each page inside the app registry to allow a native app to load any React Native page inside an Activity or ViewController as needed. Here’s how the components are registered for the MovieApp using our AppNavigator.

index.js

The AppNavigator registers all of the React Native page components, allowing the native applications to load them in any order, on an as-needed basis. If you run the MiniApp standalone, then it starts the initial screen (in this case, MovieList).

Now, let’s take a look at the MovieList component and see how it navigates to MovieDetails page

The MovieList component extends Electrode Native Navigation’s Component class which in turn extends React.Component. The navigationOptions allows any React Native component to take control of the native navigation bar if they choose to do so, which is beneficial when using a MiniApp from inside a larger native application.

The onNavButtonPress(buttonId) override allows the MovieList component to listen and respond to navigation bar button clicks.

Finally, let’s look at how the page navigation works. When a user clicks the View Details button, the component makes a call to navigateInternal(…) with the name of the next page and the required props. This call will be sent to the native handler via the Electrode Native bridge for processing.

onDetailPress={() => this.navigateInternal('MovieDetails', { movie: movies[activeMovieIndex], configuration, genres })}

Now, let’s take a look at how the native implementation handles these navigate calls.

Android

The native app starts a FragmentActivity and loads the first Fragment with the MovieList component. The View Details button click initiates a navigation call to the MovieDetails page. The native implementation handles this request by starting a new Fragment instance with the MovieDetails view inside it and so on, as demonstrated here:

MovieListActivity (FragmentActivity)

R.layout.activity_main

When the MovieListActivity is launched, the onCreate() method of the ElectrodeBaseActivity will create an instance of the ElectrodeReactFragmentDelegate and load the Fragment instance inside of the fragment_container defined in your activity_main.xml resource file.

MiniAppNavFragment can also overridenavigate(Route route)in case you need to handle a navigation request initiated by React Native.

If navigate(Route route) is not overridden by either the Activity or the Fragment, it falls back to the default behavior wherein a new instance of MiniAppNavFragment is created and loaded with the specified React Native component.

This design makes the React Native component easily consumable by an Android developer into a preexisting native app.

Electrode Native autogenerates this code whenever a MiniApp is created. This eliminates the need for a React Native developer to learn to write any integration code to run the MiniApp standalone.

iOS

Similarly for iOS, a UINavigationController would first host the root component inside a MiniAppViewController; each subsequent navigate() call from React Native would create a new MiniAppViewController and load the requested React Native view component inside it.

MovieListViewController (UINavigationController)

When the MovieListViewController is launched, the viewDidLoad() will delegate the control to the ENNavigationDelegate to start a new MiniAppViewController with the rootComponent as the view.

MiniAppViewController

You can always extend the MiniAppViewController to create a custom ViewController and to override any method based on your requirements. For example, to customize a navigate() call, you may override the handleNavigateRequestWithPath function inside your CustomViewController.

You also have the option to handle this override on the MovieListViewController level by overriding its navigateWithRoute method.

Without any overrides in place, the default implementation will be executed, starting a new instance of the MiniAppViewController with the given React Native component view inside it.

Who is using ern-navigation?

Walmart’s Online Grocery application is the biggest consumer of the Electrode Native Navigation framework, with more than 90% of the application currently using React Native. Additionally, this framework is in use by many applications across Walmart.com, Walmart Canada, and Walmart Grocery as well as other internal Walmart associate-facing applications.

Credits

This article, as well as the Electrode Native Navigation framework, was designed and written by engineers on the WalmartLabs Electrode Native team — Adam Sharp, Deepu Eswarath Ganapathiyadan, and Lianci Liu — under the soft, supple hand of Richard Mercille (you’re welcome, Richard).

Special thanks for the support of the entire Electrode Native team and all of the different Walmart application teams who have helped us along the way — giving us some really long nights and awesome migraines — and we mean that in the best of ways.

Further Reference:

--

--