How to Build an Ecommerce React Template
Tags: react, javascript, programming, api
Published: 2022-05-20 12:46:55

---
title: How to Build an Ecommerce React Template
published: true
date: 2022-05-19 12:17:49 UTC
tags: react,javascript,programming,api
canonical_url: https://javascript.plainenglish.io/how-to-build-an-ecommerce-react-template-bd27f7687f77
---

#### Chapter 2: Step by step guide on how to consume a RESTful API on React

![How to Build an Ecommerce React Template - Chapter 2](https://cdn-images-1.medium.com/max/1024/1*VqqlsfG4rVl61q1pZM-FVg.png)
_Consume a RESTful API on React_

In the first [chapter](https://javascript.plainenglish.io/how-to-build-an-ecommerce-reactjs-template-chapter-1-the-beginning-bf67f0500e92), we created a basic React app with [Tailwind CSS](https://tailwindcss.com/) and [React Router](https://reactrouter.com/). Also, we created a static home page with products object.

In this chapter, we going to consume our RESTful API on React for the home page product list.

### Chapter 2: Consume a RESTful API on React

In this chapter, we going to do the below tasks:

- 1. Create API
- 2. Remove home page product object
- 3. Consume API
- — 3.1 Creating a state
- — 3.2 API request
- — 3.3 Render products

#### 1. Create API

For the demo, we going to create an internal API by using a JSON file. So create a products.json file on the “public/data/” folder. Copy the below JSON data on products.json

public/data/products.json

```
{
  "products": [
    {
      "id": 1,
      "name": "iPhone 12 Pro",
      "href": "#",
      "price": "$999.99",
      "brand": "Apple",
      "category": "Cell Phones",
      "thumbnail": "https://images.unsplash.com/photo-1611791483458-6da70329aac6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80"
    },
    {
      "id": 2,
      "name": "iPhone 13 Pro Max",
      "href": "#",
      "price": "$1200",
      "brand": "Apple",
      "category": "Cell Phones",
      "thumbnail": "https://images.unsplash.com/photo-1632633728024-e1fd4bef561a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80"
    },
    {
      "id": 3,
      "name": "HP Laptop",
      "href": "#",
      "price": "$800",
      "brand": "HP",
      "category": "Computers",
      "thumbnail": "https://images.unsplash.com/photo-1496181133206-80ce9b88a853?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80"
    },
    {
      "id": 4,
      "name": "Apple Laptop",
      "href": "#",
      "price": "1600",
      "brand": "Apple",
      "category": "Computers",
      "thumbnail": "https://images.unsplash.com/photo-1453928582365-b6ad33cbcf64?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80"
    },
    {
      "id": 5,
      "name": "Google pixel 6",
      "href": "#",
      "price": "$1000",
      "brand": "Google",
      "category": "Cell Phones",
      "thumbnail": "https://images.unsplash.com/photo-1635870664257-430f094c25db?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80"
    },
    {
      "id": 6,
      "name": "Sony headphone",
      "href": "#",
      "price": "$499.99",
      "brand": "Sony",
      "category": "Headphones",
      "thumbnail": "https://images.unsplash.com/photo-1546435770-a3e426bf472b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80"
    },
    {
      "id": 7,
      "name": "Apple AirPods",
      "href": "#",
      "price": "$222.99",
      "brand": "Apple",
      "category": "Headphones",
      "thumbnail": "https://images.unsplash.com/photo-1600294037681-c80b4cb5b434?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80"
    },
    {
      "id": 8,
      "name": "Canon camera",
      "href": "#",
      "price": "$999.99",
      "brand": "Canon",
      "category": "Cameras",
      "thumbnail": "https://images.unsplash.com/photo-1500646953400-045056a916d7?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&h=400&q=80"
    }
  ]
}
```

We can also get a full fake REST API with zero coding by using [JSON Server](https://github.com/typicode/json-server). But in this chapter, we just added a JSON file to the public folder.

#### 2. Remove home page product object

Remove the const products on the Home page component src/pages/Home.js

```
+++ b/src/pages/Home.js
@@ -1,102 +1,64 @@
 import React from 'react';
 
-const products = [
- {
- id: 1,
- name: 'Product Name',
- href: '#',
- price: '$9.99',
- imageSrc: '[https://images.unsplash.com/photo-1555982105-d25af4182e4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'](https://images.unsplash.com/photo-1555982105-d25af4182e4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'),
- },
- {
- id: 2,
- name: 'Product Name',
- href: '#',
- price: '$10.99',
- imageSrc: '[https://images.unsplash.com/photo-1508423134147-addf71308178?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'](https://images.unsplash.com/photo-1508423134147-addf71308178?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&h=400&q=80'),
- },
- {
- id: 3,
- name: 'Product Name',
- href: '#',

```

#### 3. Consume API

To consume the API, we need to make an AJAX request. We going to use the browser built-in [window.fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) method for the API request.

#### 3.1 Creating a state

We going to create a component state object to store the fetched products. Create constructor function and add initial state object values. The isLoaded is used to display the loading message.

```
class Home extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoaded: false,
      products: []
    };
  }
```

#### 3.2 API request

We going to use [componentDidMount](https://reactjs.org/docs/react-component.html#mounting) the lifecycle method to load data from a remote endpoint.

_componentDidMount() is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request._

```
componentDidMount() {
  fetch("/data/products.json")
    .then(res => res.json())
    .then(
      (result) => {
        this.setState({
        isLoaded: true,
        products: result.products
        });
      }
    )
}
```

#### 3.3 Render products

Copy the below render() method on your Home component.

```
import React from 'react';

class Home extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoaded: false,
      products: []
    };
  }

componentDidMount() {
    fetch("/data/products.json")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            products: result.products
          });
        }
      )
  }

render() {
    const { isLoaded, products } = this.state;
    return (
      <div>
        <section className="bg-white py-8">
          <div className="container mx-auto flex items-center flex-wrap pt-4 pb-12">
            <nav id="store" className="w-full z-30 top-0 px-6 py-1">
              <div className="w-full container mx-auto flex flex-wrap items-center justify-between mt-0 px-2 py-3">
                <a className="uppercase tracking-wide no-underline hover:no-underline font-bold text-gray-800 text-xl " href="#">
                  Store
                </a>
                <div className="flex items-center" id="store-nav-content">
                  <a className="pl-3 inline-block no-underline hover:text-black" href="#">
                    <svg className="fill-current hover:text-black" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                      <path d="M7 11H17V13H7zM4 7H20V9H4zM10 15H14V17H10z" />
                    </svg>
                  </a>
                  <a className="pl-3 inline-block no-underline hover:text-black" href="#">
                    <svg className="fill-current hover:text-black" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                      <path d="M10,18c1.846,0,3.543-0.635,4.897-1.688l4.396,4.396l1.414-1.414l-4.396-4.396C17.365,13.543,18,11.846,18,10 c0-4.411-3.589-8-8-8s-8,3.589-8,8S5.589,18,10,18z M10,4c3.309,0,6,2.691,6,6s-2.691,6-6,6s-6-2.691-6-6S6.691,4,10,4z" />
                    </svg>
                  </a>
                </div>
              </div>
            </nav>
            {!isLoaded ? (
              <div class="w-full">
                <div class="flex items-center justify-center">
                  Loading...
                </div>
              </div>
            ) : (
            <div className="grid grid-cols-1 gap-y-10 sm:grid-cols-2 gap-x-6 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
              {products.map((product) => (
                <a key={product.id} href={product.href}>
                  <img className="hover:grow hover:shadow-lg" src={product.thumbnail} />
                  <div className="pt-3 flex items-center justify-between">
                    <p className="">{product.name}</p>
                    <svg className="h-6 w-6 fill-current text-gray-500 hover:text-black" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                      <path d="M12,4.595c-1.104-1.006-2.512-1.558-3.996-1.558c-1.578,0-3.072,0.623-4.213,1.758c-2.353,2.363-2.352,6.059,0.002,8.412 l7.332,7.332c0.17,0.299,0.498,0.492,0.875,0.492c0.322,0,0.609-0.163,0.792-0.409l7.415-7.415 c2.354-2.354,2.354-6.049-0.002-8.416c-1.137-1.131-2.631-1.754-4.209-1.754C14.513,3.037,13.104,3.589,12,4.595z M18.791,6.205 c1.563,1.571,1.564,4.025,0.002,5.588L12,18.586l-6.793-6.793C3.645,10.23,3.646,7.776,5.205,6.209 c0.76-0.756,1.754-1.172,2.799-1.172s2.035,0.416,2.789,1.17l0.5,0.5c0.391,0.391,1.023,0.391,1.414,0l0.5-0.5 C14.719,4.698,17.281,4.702,18.791,6.205z" />
                    </svg>
                  </div>
                  <p className="pt-1 text-gray-900">{product.price}</p>
                </a>
              ))}
            </div>
            )}
          </div>
        </section>
      </div>
    );
  }
}

export default Home;
```

The complete working code of this chapter is pushed and available on Github — [archive/Chapter\_2](https://github.com/balajidharma/tailwindcss-nordic-store/tree/archive/Chapter_2).

**Full Demo:**

[React App](https://balajidharma.github.io/tailwindcss-nordic-store/)

**Previous:** [Chapter 1: Step by step guide on how to build a React Ecommerce template using Tailwind CSS](https://javascript.plainenglish.io/how-to-build-an-ecommerce-reactjs-template-chapter-1-the-beginning-bf67f0500e92)

**Next:** Coming soon

Thank you for reading.

Stay tuned for more!

_Follow me at_ [**_balajidharma.medium.com_**](https://balajidharma.medium.com/).

_More content at_ [**_PlainEnglish.io_**](https://plainenglish.io/)_. Sign up for our_ [**_free weekly newsletter_**](http://newsletter.plainenglish.io/)_. Follow us on_ [**_Twitter_**](https://twitter.com/inPlainEngHQ) _and_ [**_LinkedIn_**](https://www.linkedin.com/company/inplainenglish/)_. Check out our_ [**_Community Discord_**](https://discord.gg/GtDtUAvyhW) _and join our_ [**_Talent Collective_**](https://inplainenglish.pallet.com/talent/welcome)_._

* * *