Deepak Grover

@metagrover

Building An E-commerce Search App with React Native

We will go over the process of building a starter e-commerce mobile app for searching through a books datastore using React native. If you have never worked with React Native before, this can act as a kickstart to your mobile app development journey with Javascript! 🎉

Some context first! It’s 2018 and JavaScript is growing faster than ever before. The entire community has been working hard to make the web more and more accessible. Everything starting from the libraries and frameworks, to the dev tools required to build the apps, have matured gracefully. Sure, there has been some chaos amidst these improvements. But it is just fascinating that if you know JS today, you can build a web app, a backend server and even mobile apps.

React Native enables building native mobile apps using JavaScript and React. Unlike Cordova/Ionic/Phonegap that also lets you build mobile apps using JavaScript with WebViews, React Native compiles entirely to a native app and also allows writing native (Swift, Objective-C, Android) code when required.

Things you need to know before getting started 👶

You should have some (if not much) experience writing React. It is fairly easy to get started with and has good resources available online that can help. If you are new to the subject, you can start with the official tutorial. And, if you prefer videos over text, I highly recommend Kent C. Dodds’s free course on Egghead — The Beginner’s Guide to ReactJS.

It’d be best if you have a fair understanding of ES6+ as well. I’ve got you covered with that. I wrote a kickstarter guide to writing ES6 which should put you on track in no time. 💪

You don’t necessarily have to spend a lot of time learning react and building web apps. (Although I’d recommend you to do that). But if you quickly want to get started with React Native, get yourself familiarised with React’s basic fundamentals because React Native and React share the same core principles for building apps. They just target two different clients — web and native.

Here, I want to highlight the fact that if you use React and React Native in production, you can end up with a lot of shared code across all the platforms (web, iOS and Android). This will enable you to maintain bigger projects with less development time and costs 😉. This is one of the reasons why React Native is starting to see industry wide adoption: Airbnb, Facebook, Instagram, Walmart, Tesla have their mobile apps built using RN.

Basic Concepts 👩‍🎓

Let’s start by briefly discussing how React Native works and how the JavaScript code actually translates into a kickass native mobile app.

Any React Native application runs in two threads:

1. Main thread

This thread manages the user interface of your app and processes all the native interactions including gestures and touch. Since React Native also allows you to add in native code written in Android Java, Objective C or Swift, these chunks of code get executed on this thread.

2. JavaScript thread

This executes the JavaScript code that you write in a separate JavaScript engine (which is present in iOS by default and gets shipped to Android devices with the build).

For the application to work, these two threads need to talk to each other, which is what Bridge is for.

React Native core architecture

Bridge, as the name suggests, helps in the data (message) transactions between the JavaScript thread and the Main Native thread. These messages can be asynchronous or batched. Bridge enables one’s JavaScript code to talk to the native modules and interact with the device APIs.

Now that we have the basic understanding of react native architecture, let’s get into the implementation details.

Setting up the development environment 💻

If you already have React Native installed and are familiar with the development ecosystem, you can skip ahead to the next section.

For those of you, who are just getting started, you can either follow the official setup guide here (which is more detailed), or follow along with me here:

Make sure you have node installed in your system.

We will be using the create-react-native-app (CRNA) tool for setting up the boilerplate.

npm install -g create-react-native-app

Then run the following commands to create a new React Native project, say HelloNative:

create-react-native-app HelloNative
cd HelloNative
npm start

This will start a development server for you, and print a QR code in your terminal.

The only caveat of using create-react-native-app here is that it may not use the latest version of react-native. If that bothers you, you can use Expo CLI or Expo XDE which are also fairly simple to get started with.

Next step is to install the Expo client app on your iOS or Android phone and connect to the same wireless network as your computer. Using the Expo app, you can scan the above generated QR code from your terminal and open your project directly in your phone. How cool is that!

At this point, your app should look like this:

React Native app

If you wish to run this app on an emulator, you can run:

npm run ios for iOS and,

npm run android for Android emulator.

This will install Expo client on the emulator and run your react-native app.

If you now open the developer menu in the app, you’d see options to enable Hot Reloading and Live Reload. These allow you to reload your app instantly, which is a major advantage if you come from Android development background where it takes ages for gradle to finish building.

A closer look at the developer options

The developer options come bundled with debugging features as well. We will get into the details of it in the next section.

Debugging and troubleshooting ⚒

Debugging Remote JS feature in the developer menu allows us to browse through any console messages or errors in the browser. This comes super handy while you’re building apps.

Additionally, you may want to install React Native debugger while you’re at it.

React Native Debugger in action

This is a nifty tool that allows us to browse through the component state and props tree in React Native apps. It also enables you to browse and edit the styles that are being applied to the components present in your app, serving as a replacement for chrome-dev-tools here.

🔋 Batteries included

React Native comes with a range of built-in components that you can use to build apps with. You can browse through the list of available components here where in you will find some of these components to be platform specific — under Android specific and iOS specific sections.

These components will help you put together simple UIs for your app. Similar to web, React Native supports fetch enabling you to make http requests and get data from your server.

For our 📗 booksearch app, we will be using Elasticsearch, which is a NoSQL database which can search through large amounts of data in a short time. It performs a full-text search on the data which is stored in the form of documents (which are JSON objects) by examining all the words in every document.

Even if you’ve never used Elasticsearch before, you should be able to follow along with this tutorial.

Elasticsearch may not seem like an easy thing to get started with. The setup, adding or viewing data and generating query can seem a bit overwhelming if you are a beginner. That’s why, we, at Appbase, have built some open-source tools to help you do all these things with the matter of some clicks 😉

  • Tool to add data into Elasticsearch — Importer 🗃
  • Tool to view Elasticsearch data like an excel sheet — Data Browser 👀
  • Tool to generate relevant Elasticsearch queries — Query Builder 🔨

In this blog post, with the help of some of these tooling, we will utilize the strengths of Elasticsearch ⚡️ with React Native to build a rich mobile bookstore app.

You can set up and install an Elasticsearch server by following the official installation guide, or you can create a free account at appbase.io which provides Elasticsearch hosting as a service and is easy to use. For simplicity, we will be using appbase.io service to get started with.

I’ve already created an appbase app with books dataset for simplicity. You can check out the dataset over here.

Dataset of books

You can clone this dataset and generate credentials for your very own app by clicking on the Clone this app button on the bottom left.

These credentials will be used to connect our UI with this app. The credentials of the above app which we will be using in this tutorial are:

{
    app: "good-books-ds",
    credentials: "nY6NNTZZ6:27b76b9f-18ea-456c-bc5e-3a5263ebc63d",
    type: "good-books-ds"
}

Say hello 👋 to Reactivesearch 🔍

We will be using ReactiveSearch, an open-source React and React Native UI components library for Elasticsearch that I am a contributor to. It offers a range of highly customizable rich UI components that can connect with any Elasticsearch server and provide you an appropriate default configuration for all generic use-cases (like E-commerce, Yelp, Meetups, etc) bundled into these components.

Wait, why do I need ReactiveSearch now?
ReactiveSearch simplifies the entire process of connecting to an Elasticsearch index, making queries, fetching and rendering results in sleek UI, not just that, it also lets you make your components talk to each other, i.e. if Component-A gets updated, Component-B gets to know and it can update itself without needing any manual interaction.
This whole component-to-component subscription comes in handy when you have dynamic filters present on your screen, such as in case of e-commerce apps where Selecting a category of Appliances, also changes the sub-categories available, their prices and what not.
ReactiveSearch helps you create significantly smarter apps easily and in a declarative fashion.
Reactivesearch-native bundles a range of native UI components that enables you to build UIs like Airbnb, meetups, etc seamlessly. You can find the complete list of available components here.
Reactivesearch Native Components

Building the 📚 BookSearch app

First things first, we need to install reactivesearch-native in our React Native project by running:

npm install @appbaseio/reactivesearch-native

All the ReactiveSearch components are wrapped around a container component called ReactiveBase which connects our UI components with the Elasticsearch cluster.

We’ll use this in App.js:

Notice how we have used Flex based styling here. Styling in React Native is very much similar to that of web. If you’ve no experience using flex, I highly recommend FlexBox Froggy to begin with.

Besides Stylesheet, we have used two other components from React Native in our code snippet:

  • View - This is similar to a div html element in React Native ecosystem. It is a container that supports layout with flexbox, style, some touch handling, and accessibility controls.
  • Text - This is a simple native component for displaying text. You can read more about it here.

For our BookSearch app, we will need two components from reactivesearch-native in our layout:

1. Search box for searching the books:

Here, we will use DataSearch component from reactivesearch-native. It creates a search UI component and enables us to search across one or more fields in our dataset easily. It looks like this:

<DataSearch
    componentId="searchbox"
    dataField={[
        'original_title',
        'original_title.search',
        'authors',
        'authors.search',
    ]}
    placeholder="Search for books"
    autosuggest={false}
/>

This DataSearch component queries on the given dataField(s) in the dataset. This component goes inside the ReactiveBase component and receives all the necessary data from it so we don’t have to write Elasticsearch queries ourselves.

Notice how we have used .search fields in our dataField prop here. authors.search is a multi-field of the authors field. Elasticsearch can index the same data in different ways for different purposes, which we can use to get better search results.

2. Result List View for displaying the search results:

For displaying results, we will be using ReactiveList component from reactivesearch-native. Here’s what it looks like:

<ReactiveList
    componentId="results"
    dataField="original_title"
    size={7}
    showResultStats={false}
    pagination={true}
    react={{
        and: "searchbox"
    }}
    onData={(res) => (
        <View style={styles.result}>
        <Image source={{ uri: res.image }} style={styles.image} />
        <View style={styles.item}>
            <Text style={styles.title}>{res.original_title}</Text>
            <Text>{res.authors}</Text>
        </View>
        </View>
    )}
/>

Here’s how its props work:

  • dataField: orders the results using name field here.
  • react: specifies that it should construct a query based on the current selected values of searchbox component. Every time the user changes the input value in the searchbox, a new query is fired — you don’t need to write a manual query for any of the UI components here, they are preset with a default config to meet all the generic use-cases, but if you wish, you can override it via customQuery prop.
  • onData: accepts a function which should return a valid JSX representing a list-item in the result list. This prop will be used to render the list of results.

You can read all about its prop usage here.

Reactivesearch is built on top of native-base 💯 which uses some fonts which can be included by adding:

async componentWillMount() {
  await Expo.Font.loadAsync({
    Roboto: require('native-base/Fonts/Roboto.ttf'),
    Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
    Ionicons: require('@expo/vector-icons/fonts/Ionicons.ttf'),
  });
}

With these components and some styling 💅 magic, here’s what our app looks like:

Voila! You‘ve a BookSearch app that runs on Android & iOS
If you wish to play around with this app on the fly, try this snack here 🎉

Useful links

  1. ReactiveSearch GitHub repo 🌟
  2. ReactiveSearch docs

Hope you enjoyed this tutorial. If you have any thoughts or suggestions, please let me know and do share your version of the app in the comments 😉

Topics of interest

More Related Stories