Creating an E-commerce Site with MERN Stack — Part III

Tókos Bence
7 min readJan 15, 2024

--

Introduction

Create React App is a popular command-line interface tool that allows developers to quickly and easily set up a new React project with a pre-configured development environment. This means that you can jump straight into building your application without having to worry about configuring and setting up the tools and dependencies needed for a React project.

Let’s do the magic! :)

  1. First, make sure you have Node.js installed on your computer. You can download the latest version from the official Node.js website.
  2. Open up your terminal or command prompt and navigate to the directory where you want to create your new React project.
  3. Type the following command and hit enter:
npx create-react-app frontend

4. Wait for the installation process to finish. Once it’s done, navigate to the project directory:

cd frontend

5. Finally, start the development server by typing:

npm start

This will start a development server at http://localhost:3000, and you can see your React app running in the browser. That’s it! You now have a fully functional React project set up and ready to be developed further.

Once you see the running app on port 3000, delete almost everything from the App.js file. We need to work here. After deleting everything, your App.js should look like this:

import "./App.css";

function App() {
return <div></div>;
}

export default App;

React Router

React Router is a library that helps you handle client-side routing in your React applications. It provides a declarative way to define routes and render the appropriate components based on the current URL.

To define routes in your application using React Router v6, you can use the Routes component, which takes a list of Route components as its children. Each Route component maps a URL path to a component to render.

The Route component specifies a path and a component to render when the path matches the current URL. You can also specify optional parameters and query strings in the path, which can be accessed as props in the rendered component.

React Router provides a flexible and powerful way to handle routing in your React applications, making it easy to create complex single-page applications.

First, we need to install:

npm install react-router-dom

Create a new folder in the /src directory named pages. Then, inside the /pages folder, create a new file named HomePage.js. This file will serve as our home page.

Add the following code to the HomePage.js:

import React from "react";

const HomePage = () => {
return (
<React.Fragment>
<h2>My HomePage</h2>
</React.Fragment>
);
};

export default HomePage;

To create our first route, go back to App.js. Import the necessary packages and add the following code:

//importing Route and Routes from the React router library
import { Route, Routes } from "react-router-dom";

//import the HomePage
import HomePage from "./pages/HomePage";

function App() {
return (
<ApolloProvider client={client}>
<Routes>
<Route path="/" element={<HomePage />} />
</Routes>
</ApolloProvider>
);
}

Before running the app, you need to make the following changes to the index.js file. Import the necessary library and wrap the app component.

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);

reportWebVitals();

If you run the application now, you will see “My HomePage” displayed on your screen. Congratulations, you have created your first route! :)

Axios

Axios is a popular JavaScript library used for making HTTP requests from web browsers and Node.js. It provides a simple and easy-to-use API for sending HTTP requests and handling responses in various formats such as JSON, XML, and FormData. Axios supports a wide range of features such as cancellation of requests, automatic request retries, and interceptors to modify requests or responses before they are processed. It is widely used in modern web applications and is often used with other libraries and frameworks like React or Vue.js.

We will also use axios, a library that is preferred by many big companies and has a large community for debugging and practice. To install axios, use the following command:

npm i axios

After installing axios, return to HomePage.js and create a function to call our first API endpoint.

import React, { useEffect, useState } from "react";
import axios from "axios";

const HomePage = () => {
const [productList, setProductList] = useState([]);

useEffect(() => {
getProduct();
}, []);

const getProduct = async () => {
try {
const response = await axios.get("http://localhost:5000/read");
setProductList(response.data);
console.log(response.data);
} catch (e) {
console.log(e);
}
};

return (
<React.Fragment>
<h2>My HomePage</h2>
</React.Fragment>
);
};

export default HomePage;

In this code snippet, we are creating a functional component in React called “HomePage”. This component is using two hooks from React, “useEffect” and “useState”.

The “useState” hook is used to declare and initialize a state variable called “productData”, which is an empty array. We will use this variable to store data we fetch from the server.

The “useEffect” hook is used to make a call to a Node.js/Express server using the Axios library. We are making a GET request to the URL “http://localhost:5000/read" which should return data in JSON format. If the request is successful, we update our state variable “productData” with the response data using the “setProductData” function.

Finally, we are returning some JSX code which renders the heading “My HomePage”.

To use this component, we need to import it into another component and render it in the DOM. The code also needs to be connected to a Node.js/Express server which provides the data that we are fetching with Axios.

Probably you still haven’t seen any changes, but if you right-click and inspect the page, you will see the response result in JSON format in the console.

For printing on the screen go back and edit the code:

return (
<React.Fragment>
<h2>My HomePage</h2>
<h2>{productList[0].title}</h2>
</React.Fragment>
);

When the HomePage component mounts, it initializes the productData state as an empty array using the useState hook. Then, the useEffect hook calls the getProduct function, which sends a GET request to the server using Axios to retrieve an array of products. Once the server responds, the productData state is updated with the received array of products.

In the return statement, the title of the first product is displayed using the productData[0].title syntax. However, if the productData array is empty or the server response has not yet been received, an error may occur because the code is trying to access the title property of an undefined value.

Great! We have arrived here and made an API call from the frontend to the backend, successfully connecting them together. This is a great improvement!

Material UI

Material UI is a popular open-source library for building user interfaces in React applications. It provides a set of pre-built, customizable components that follow the Material Design guidelines, making it easy to create beautiful and responsive UIs. Material UI also includes a robust theming system, allowing developers to easily customize the look and feel of their applications. It is widely used and has a large community, making it easy to find support and resources online.

For installing we need the basic libraries:

npm install @mui/material @emotion/react @emotion/styled

Let’s create a minimal interface for our app and create our second component which will be a card component for our product.

Go to the /src folder and create a folder components and inside the components folder create a ProductCard.js:

import React, { useState } from "react";
import Typography from "@mui/material/Typography";
import Card from "@mui/material/Card";
import CardHeader from "@mui/material/CardHeader";
import CardMedia from "@mui/material/CardMedia";
import CardContent from "@mui/material/CardContent";
import Rating from "@mui/material/Rating";
import Stack from "@mui/material/Stack";

const ProductCard = (props) => {
const [product, setProduct] = useState(props.product);

return (
<React.Fragment>
<Card
sx={{
width: 345,
height: 550,
display: "flex",
justifyContent: "space-between",
flexDirection: "column",
}}
>
<CardHeader title={product.title} />
<CardMedia
component="img"
height="194"
image={product.images}
alt="Product image"
/>
<CardContent>
<Stack direction="column" spacing={1}>
<Typography variant="body2" color="text.secondary">
{product.description}
</Typography>
<Stack direction="row" spacing={1}>
<Rating
name="half-rating-read"
defaultValue={product.rating}
precision={0.5}
readOnly
/>
<Typography variant="body1" color="text.primary">
{product.rating}
</Typography>
</Stack>
<Stack direction="column">
<Typography variant="body1" color="text.primary">
{product.price} $
</Typography>
<Typography variant="body1" color="text.primary">
Price discount: {product.discountPercentage}%
</Typography>
</Stack>
</Stack>
</CardContent>
</Card>
</React.Fragment>
);
};

export default ProductCard;

This code is a React functional component that renders a card containing product information. The component imports several Material-UI components such as Typography, Card, CardHeader, CardMedia, CardContent, Rating, and Stack.

The product information is passed as a prop to the ProductCard component and is initially stored in the product state using useState hook. The component then returns a Card component with the product details such as title, image, description, rating, price, and discount percentage.

The title of the product is displayed in the CardHeader component, and the product image is rendered using the CardMedia component. The product description is displayed using the Typography component, and the product rating is displayed using the Rating component.

The product price and discount percentage are also displayed using the Typography component. These values are stored in the product state and accessed using the dot notation. The Stack component is used to create a layout and spacing for the product information.

Overall, the ProductCard component is a reusable component that can be used to render product information in a clean and organized manner.

Now, let’s navigate back to the HomePage component and proceed to import and use the ProductComponent within it:

import React, { useEffect, useState } from "react";
import axios from "axios";

import ProductCard from "../components/ProductCard";

const HomePage = () => {
const [productList, setProductList] = useState([]);

useEffect(() => {
getProduct();
}, []);

const getProduct = async () => {
try {
const response = await axios.get("http://localhost:5000/read");
setProductList(response.data);
console.log(response.data);
} catch (e) {
console.log(e);
}
};

return (
<React.Fragment>
{productList.length !== 0 &&
productList.map((product) => <ProductCard product={product} />)}
</React.Fragment>
);
};

export default HomePage;

Finally

In this article, we learned how to set up a new React project using Create React App, and how to add routing using React Router v6. We also saw how to make HTTP requests to an API using the Axios library. By following the steps outlined in the article, we were able to create a fully functional React project with a homepage, route, and API integration.

In the next article, we will improve the user interface and add more functionality to our project.

--

--

Tókos Bence

Hi everyone! I'm an enthusiastic full-stack developer. Please feel free to reach out to me via email (tokosbex@gmail.com) or Twitter (@tokosbex).