DEV Community

Balaji Dharma
Balaji Dharma

Posted on • Originally published at javascript.plainenglish.io on

How to Build an Ecommerce React Template

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

How to Build an Ecommerce React Template - Chapter 2
Consume a RESTful API on React

In the first chapter, we created a basic React app with Tailwind CSS and React Router. 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"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

We can also get a full fake REST API with zero coding by using 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: '#',

Enter fullscreen mode Exit fullscreen mode

3. Consume API

To consume the API, we need to make an AJAX request. We going to use the browser built-in window.fetch 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: []
    };
  }
Enter fullscreen mode Exit fullscreen mode

3.2 API request

We going to use componentDidMount 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
        });
      }
    )
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

The complete working code of this chapter is pushed and available on Github — archive/Chapter_2.

Full Demo:

React App

Previous: Chapter 1: Step by step guide on how to build a React Ecommerce template using Tailwind CSS

Next: Coming soon

Thank you for reading.

Stay tuned for more!

Follow me at balajidharma.medium.com.

More content at PlainEnglish.io. Sign up for our free weekly newsletter. Follow us on Twitter and LinkedIn. Check out our Community Discord and join our Talent Collective.


Top comments (0)