Mobile application developers work on a variety of projects, including e-commerce mobile applications that customers can use to buy products online. The number of smartphone users in the world is increasing dramatically every day, so every company selling products may want to offer convenient purchasing services through e-commerce mobile applications.

These applications consist of several common screens, such as product list, product details page, shopping cart, checkout area, and registration/login page. Some mobile applications may also have room for customer comments, personal Settings, and many other features. Like other enterprise apps, mobile apps need to be distributed to Google Play and Apple’s App Store to reach a wide audience of customers.

React Native app on GitHub versus building your own app from scratch

Mobile application developers often prefer to build their applications with cross-platform frameworks in order to deliver projects quickly. This is partly why React Native is a popular framework for building cross-platform mobile apps — it makes it easy for developers to build Native apps in a React based development environment.

Most freelance developers start by looking for the open source React Native e-commerce application template and customizing it to their users’ needs. But most of the existing React Native e-commerce app templates on GitHub use a bit of complex Redux for centralized state management purposes, and many of these projects include things you don’t need.

With that in mind, it’s probably a smarter decision to create your own React Native e-commerce app template from scratch. In this tutorial, I’ll explain how to do that.

What are we going to build?

We will build an e-commerce mobile application with several common (and therefore customizable) features. The application has the following three screens.

  1. Product screen

    The Product screen lists several products and serves as the home page for the application. Each product item has a title, price, and picture.
  2. Product details The screen

    When a user clicks on a specific product item on the product page, the application takes the user to the product details screen. The product Details screen shows all the information about the current product. There is also a button to add products to the cart; When the user clicksAdd to shopping cartWhen pressed, the number of items on the cart icon is updated.
  3. Shopping basket screen

    This screen shows a summary of all the products added to the basket. It displays a list of products with product name, quantity, subtotal, and total.

Build e-commerce applications with React Native

Let’s create a new React Native project. In this tutorial, I’ll use the Expo CLI to build an e-commerce application.

You can use the React Native CLI or Expo CLI to build React Native apps, but if you use the React Native CLI, you’ll need to set up your own developer environment. For example, if you need to test your application on an Android device, you’ll need to set up the Required Android SDK.

On the other hand, the Expo CLI lets you develop React Native applications without having to install any mobile development SDKs on your computer.

Set up a new React Native project

Run the following command to install the Expo CLI. Make sure that both your Node.js and NPM have a newer version of LTS.

Note: If you’re building on an Ubuntu operating system, NVM is a great tool to install to track and update to the latest Node LTS releases.

 npm install -g expo-cli

Copy the code

The following command will create a new React Native project.

expo init e-commerce-app

Copy the code

If it asks for a template, select the blank template option. After that, run the following command to start developing the application.

npm start
# or
yarn start 

Copy the code

Now you can see your code changes along with the Expo Go mobile app. (It’s available on both the Play Store and App Store.) I’ll demonstrate the application on an Android device.

Use your phone to scan the QR code given by the above command to open your app.

Creating a product list

We are creating a multi-screen mobile application, and the product list is a screen of the application. We can use the React Native navigation extension to build multi-screen applications.

Install the popular React Navigation package with the following command.

npm install @react-navigation/native
expo install react-native-screens react-native-safe-area-context
npm install @react-navigation/native-stack

Copy the code

Product information is usually retrieved through web apis. But, for now, let’s create a mock API service to get a few products and get our mobile application running. In. / services/ProductsService. Js file to add the following code.

const PRODUCTS = [
    {
        id: 100,
        name: 'ReactProX Headset',
        price: 350,
        image: require('../assets/products/headset-100.jpg'),
        description: 'A headset combines a headphone with microphone. Headsets are made with either a single-earpiece (mono) or a double-earpiece (mono to both ears or stereo).'
    },
    {
        id: 101,
        name: 'FastLane Toy Car',
        price: 600,
        image: require('../assets/products/car-101.jpg'),
        description: 'A model car, or toy car, is a miniature representation of an automobile. Other miniature motor vehicles, such as trucks, buses, or even ATVs, etc. are often included in this general category.'
    },
    {
        id: 102,
        name: 'SweetHome Cupcake',
        price: 2,
        image: require('../assets/products/cake-102.jpg'),
        description: 'A cupcake (also British English: fairy cake; Hiberno-English: bun; Australian English: fairy cake or patty cake[1]) is a small cake designed to serve one person.'
    }
];
export function getProducts() {
    return PRODUCTS;
}
export function getProduct(id) {
    return PRODUCTS.find((product) => (product.id == id));
}

Copy the code

As you can see, the above service will act as a mock API server to retrieve product information. The getProducts function lists all existing products, while the getProduct function returns the product details for a given product identifier. Make sure to store your sample images in assets/ Products.

Now that we have product data, we need to create a reusable component for a single product project, because there are multiple products in the product list. Add the following code to./components/ product.js.

import React from 'react'; import {Text, Image, View, StyleSheet, TouchableOpacity} from 'react-native'; export function Product({name, price, image, onPress}) { return ( <TouchableOpacity style={styles.card} onPress={onPress}> <Image style={styles.thumb} source={image}  /> <View style={styles.infoContainer}> <Text style={styles.name}>{name}</Text> <Text style={styles.price}>$ {price}</Text> </View> </TouchableOpacity> ); } const styles = StyleSheet.create({ card: { backgroundColor: 'white', borderRadius: 16, shadowOpacity: 0.2, shadowRadius: 4, shadowRadius: 'black', shadowOffset: {height: 0, width: 0,}, elevation: 1, marginVertical: 20, }, thumb: { height: 260, borderTopLeftRadius: 16, borderTopRightRadius: 16, width: '100%', }, infoContainer: { padding: 16, }, name: { fontSize: 22, fontWeight: 'bold', }, price: { fontSize: 16, fontWeight: '600', marginBottom: 8,}});Copy the code

The product component is responsible for rendering a product when providing name, price, and image properties. This component accepts a touch event callback that opens the product details screen. As you may have noticed, some styling rules are also applied to make the product entry appear as a slightly rounded rectangle.

Build our product list

Now that we have finished with the product components, we can now start building our product list interface by reusing the product components. Add the following code to the. / screens/ProductsList. Js.

import React, {useEffect, useState} from 'react'; import { View, Text, FlatList, StyleSheet } from 'react-native'; import { Product } from '.. /components/Product.js'; import { getProducts } from '.. /services/ProductsService.js'; export function ProductsList ({navigation}) { function renderProduct({item: product}) { return ( <Product {... product} onPress={() => { navigation.navigate('ProductDetails', { productId: product.id, }); }} / >); } const [products, setProducts] = useState([]); useEffect(() => { setProducts(getProducts()); }); return ( <FlatList style={styles.productsList} contentContainerStyle={styles.productsListContainer} keyExtractor={(item)  => item.id.toString()} data={products} renderItem={renderProduct} /> ); } const styles = StyleSheet.create({ productsList: { backgroundColor: '#eeeeee', }, productsListContainer: { backgroundColor: '#eeeeee', paddingVertical: 8, marginHorizontal: 8, }, });Copy the code

The product list component gets the product list data from the mock API service we created earlier. After that, it displays product items by rendering multiple product component instances.

Before each product is rendered, we pass a navigation callback through the onPress item. Once a particular product item is selected, the navigation callback displays the product details screen.

Now our product list interface is ready.

Develop the shopping cart icon and context

The user should be able to add the currently open product to the cart from the product details screen. Now we need to implement the shopping cart logic before the product details interface.

In this case, when the user updates the cart, we need to update the summary icon of the cart (in the upper right corner of the screen). In addition, the cart summary screen lists the items in the cart.

We have to store the shopping cart data in a global location, and we need to update/retrieve them from different places. The React Context API is a great solution for this situation because it provides an easy way to have a global state, unlike other state management solutions.

Create a context for the cart in cartContext.js with the following code.

import React, {createContext, useState} from 'react';
import { getProduct } from './services/ProductsService.js';
export const CartContext = createContext();
export function CartProvider(props) {
  const [items, setItems] = useState([]);

  function addItemToCart(id) {
    const product = getProduct(id);
    setItems((prevItems) => {
      const item = prevItems.find((item) => (item.id == id));
      if(!item) {
          return [...prevItems, {
              id,
              qty: 1,
              product,
              totalPrice: product.price 
          }];
      }
      else { 
          return prevItems.map((item) => {
            if(item.id == id) {
              item.qty++;
              item.totalPrice += product.price;
            }
            return item;
          });
      }
    });
}
function getItemsCount() {
      return items.reduce((sum, item) => (sum + item.qty), 0);
  }

  function getTotalPrice() {
      return items.reduce((sum, item) => (sum + item.totalPrice), 0);
  }  

  return (
    <CartContext.Provider 
      value={{items, setItems, getItemsCount, addItemToCart, getTotalPrice}}>
      {props.children}
    </CartContext.Provider>
  );
}

Copy the code

The CarProvider class above defines a React Context for the shopping cart by exposing its actions. Now we can use this context instance to add a new shopping cart item, get a list of items, and get the total number of items.

Create a product detail interface

The Product Details section displays all information about the currently selected product. In addition, it has an add to cart button to update the cart.

In. / screens/ProductDetails. Js file to add the following code.

import React, {useEffect, useState, useContext} from 'react'; import { Text, Image, View, ScrollView, SafeAreaView, Button, StyleSheet } from 'react-native'; import { getProduct } from '.. /services/ProductsService.js'; import { CartContext } from '.. /CartContext'; export function ProductDetails({route}) { const { productId } = route.params; const [product, setProduct] = useState({}); const { addItemToCart } = useContext(CartContext); useEffect(() => { setProduct(getProduct(productId)); }); function onAddToCart() { addItemToCart(product.id); } return ( <SafeAreaView> <ScrollView> <Image style={styles.image} source={product.image} /> <View style={styles.infoContainer}> <Text style={styles.name}>{product.name}</Text> <Text style={styles.price}>$ {product.price}</Text> <Text style={styles.description}>{product.description}</Text> <Button onPress={onAddToCart} title="Add to cart" / > </View> </ScrollView> </SafeAreaView> ); } const styles = StyleSheet.create({ card: { backgroundColor: 'white', borderRadius: 16, shadowOpacity: 0.2, shadowRadius: 4, shadowRadius: 'black', shadowOffset: {height: 0, width: 0,}, elevation: 1, marginVertical: 20, }, image: { height: 300, width: '100%' }, infoContainer: { padding: 16, }, name: { fontSize: 22, fontWeight: 'bold', }, price: { fontSize: 16, fontWeight: '600', marginBottom: 8, }, description: { fontSize: 16, fontWeight: '400', color: '#787878', marginBottom: 16, }, });Copy the code

The above screen loads the product details from the mock API service based on the product identifier received from the navigation parameters. The onPress action added to the shopping cart button then updates the shopping cart context by calling the addItemToCart Context function. Finally, the contents of the screen are wrapped in SafeAreaView and ScrollView to enable vertical scrollbars to display content that doesn’t fit perfectly into the device’s viewport.

Create a shopping cart summary screen

Every customer wants to see a summary of their order before checking out. The e-commerce application has a shopping cart summary screen that lists all the shopping cart items, including product name, quantity, subtotal, and final total. At./screens/ cart.js, implement the shopping Cart screen with the following code.

import React, { useEffect, useState, useContext } from 'react'; import { View, Text, Button, FlatList, StyleSheet } from 'react-native'; import { CartContext } from '.. /CartContext'; export function Cart ({navigation}) { const {items, getItemsCount, getTotalPrice} = useContext(CartContext); function Totals() { let [total, setTotal] = useState(0); useEffect(() => { setTotal(getTotalPrice()); }); return ( <View style={styles.cartLineTotal}> <Text style={[styles.lineLeft, styles.lineTotal]}>Total</Text> <Text style={styles.lineRight}>$ {total}</Text> </View> ); } function renderItem({item}) { return ( <View style={styles.cartLine}> <Text style={styles.lineLeft}>{item.product.name} x {item.qty}</Text> <Text style={styles.lineRight}>$ {item.totalPrice}</Text> </View> ); } return ( <FlatList style={styles.itemsList} contentContainerStyle={styles.itemsListContainer} data={items} renderItem={renderItem} keyExtractor={(item) => item.product.id.toString()} ListFooterComponent={Totals} /> ); } const styles = StyleSheet.create({ cartLine: { flexDirection: 'row', }, cartLineTotal: { flexDirection: 'row', borderTopColor: '#dddddd', borderTopWidth: 1 }, lineTotal: { fontWeight: 'bold', }, lineLeft: { fontSize: 20, lineHeight: 40, color:'#333333' }, lineRight: { flex: 1, fontSize: 20, fontWeight: 'bold', lineHeight: 40, color:'#333333', textAlign:'right', }, itemsList: { backgroundColor: '#eeeeee', }, itemsListContainer: { backgroundColor: '#eeeeee', paddingVertical: 8, marginHorizontal: 8, }, });Copy the code

The code above takes the shopping cart item from the shopping cart context and displays it in a list.

Create shopping cart icon

Each e-commerce application typically displays the current number of shopping cart items with the help of a small icon in the upper right corner of the screen. Let’s create a widget to display the total number of items in the current shopping cart with the following code:./components/ carticon.js.

import React, { useContext } from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { CartContext } from '.. /CartContext'; export function CartIcon({navigation}) { const {getItemsCount} = useContext(CartContext); return ( <View style={styles.container}> <Text style={styles.text} onPress={() => { navigation.navigate('Cart'); }} >Cart ({getItemsCount()})</Text> </View> ); } const styles = StyleSheet.create({ container: { marginHorizontal: 8, backgroundColor: 'orange', height: 32, padding: 12, borderRadius: 32 / 2, alignItems: 'center', justifyContent: 'center', }, text: { color: 'white', fontWeight: 'bold', }, });Copy the code

Assemble all the components of the main application

Now, all the application components are ready to be assembled into an e-commerce mobile application. The main application component needs to include a navigation controller because we have multiple screens. In addition, we really need to wrap all the components with the shopping cart Context provider because we are using the React Context API.

As a final step, replace the code in your./ app.js file with the following code.

import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { ProductsList } from './screens/ProductsList.js';
import { ProductDetails } from './screens/ProductDetails.js';
import { Cart } from './screens/Cart.js';
import { CartIcon } from './components/CartIcon.js';
import { CartProvider } from './CartContext.js';
const Stack = createNativeStackNavigator();
function App() {
  return (
    <CartProvider>
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name='Products' component={ProductsList} 
          options={({ navigation }) => ({
            title: 'Products',
            headerTitleStyle: styles.headerTitle,
            headerRight: () => <CartIcon navigation={navigation}/>
          })}/>
          <Stack.Screen name='ProductDetails' component={ProductDetails} 
          options={({ navigation }) => ({
            title: 'Product details',
            headerTitleStyle: styles.headerTitle,
            headerRight: () => <CartIcon navigation={navigation}/>,
          })} />
          <Stack.Screen name='Cart' component={Cart} 
          options={({ navigation }) => ({
            title: 'My cart',
            headerTitleStyle: styles.headerTitle,
            headerRight: () => <CartIcon navigation={navigation}/>,
          })} />
        </Stack.Navigator>
      </NavigationContainer>
    </CartProvider>
  );
}
const styles = StyleSheet.create({
  headerTitle: {
    fontSize: 20
  }
});
export default App;

Copy the code

Conclusions and Reflections

React Native builds a cross-platform e-commerce application from the ground up. We built a minimal e-business application template without using any state management libraries. Therefore, it’s easy to build a personal application template using the demo app source in this tutorial, without having to check out all the prepared E-commerce React Native templates on GitHub, which may not be suitable for your specific needs. (Plus, you can incorporate your favorite state management library into it if you want).

The full source code can be found on my GitHub.

As for the next step, you can implement requirements such as certification, customer reviews, product reviews, inventory availability checks, etc. You will also need to plan the back end of your mobile application, as we use a mock API service in this tutorial.

If you plan to use an existing e-commerce API, you can write a service to make the API calls. If you’re building a new e-commerce API, the Node-based NoSQL back end is easy to get started.

The postBuild an ecommerce app from scratch with React Nativeappeared first onLogRocket Blog.