Lets start setting up our components, and directories. We follow certain coding patterns for each component.

So first the coding pattern we are gonna follow is.

  1. All code is camelCase.
  2. Each Component has a folder, and a css file.

For now..

Let start creating our directories.

First go to your src folder, then create a components folder.

cd src
mkdir components

Go to your components folder, and create a presentational and container folder for our presentational and container components. What are presentational and container components, well container components are “smart components” , which responsible for the functionality of the component, and renders presentational components which are responsible for display data, and inherits all it’s functionality from its container component. Here is article going deep into it.

cd components
mkdir presentational container

Now we will start creating our components. We will not implement routes until later on.

We will create our Navbar component first, it will be a container component, Since we will need it to have methods and connect the component to redux in the future.

First create Navbar folder within container folder.

cd container
mkdir Navbar

Then go within the Navbar folder, have a Navbar.js, and Navbar.css file.

cd Navbar
touch Navbar.js Navbar.css

Now lets get started creating our component. We will first import the css file, and React, with Component named export for just this step.

import React, { Component } from 'react';//Import the css file for styling.import './Navbar.css';

Now lets create our stateful component which will contain state or data that changes overtime. We will create the component by using class keyword extends Component OR React.Component they are essentially the same thing. The only difference is that we are not importing the named export Component in React for our stateless components.

Next we’ll just define it’s render method for now. The render method is the lifecycle method that returns the html of the component. If you want to learn more about lifecycle methods look at this article.

Then export it as a default export, which means they could only be one in any file, because it can be named anything you when being imported. The render method will render links that will in the future become links to the home, about, and cart components.

export default class Navbar extends Component {render() {return (<div className='nav container'><div className='desktop-nav'><p className="nav-link">Home</p><p className="nav-link">About</p><p className="nav-link">Cart</p><p className="nav-link">Login</p></div></div>);}}

Then copy and paste this to your Navbar.css file.

.nav.container {display: flex;height: 20%;width: 100%;}.desktop-nav {position: fixed;background: cyan;width: 100%;color: #fff;display: grid;grid-template-columns: 15% 15% 15% 15% 15% 15%;}.nav-link {height: 100%;font-size: 2em;color: #fff;}.nav-link:first-child {grid-column: 3/3;}.nav-link:nth-child(2) {grid-column: 4/4;}.nav-link:nth-child(3) {grid-column: 5/5;}.nav-link:nth-child(4) {grid-column: 6/6;}

Import the Navbar to the App.js. Since it is gonna be shown for every component.

import Navbar from'./components/container/Navbar/Navbar';

Now let run yarn start in one console and nodemon in another, it should look like this. NOTE: yarn start is the frontend or react, while nodemon is the backend or node. Which connects to via proxy in package.json.

Navbar component

Let’s start setting up our Home component, which we will render in the App.js. We won’t do About, Cart for this step. We will do those components when we implement our routes using react-router-dom. We will first import React, and the named export called Component, and extends or create a child of the Component class.

import React, { Component } from 'react';

Then we will define our constructor method, which initializes parent using super() and essentially gives state if there is some upon defining the class. In this case we’ll give state a products array, and a loading boolean which will be set to true. Once the products has data, we will set the loading to false therefore rendering our component.


export default class Home extends Component {
constructor() { super(); this.state ={ //Have a products and loading //products holding all your products products: [], //loading for when loader is shown //set it true, and when data is retrieve set to false. loading: true }}}

Now lets start hitting our backend, using our componentDidMount. We will perform axios calls or side effects which will retrieve the data. Underneath our react import. We’ll import axios from the axios npm module. Here is axios documentation.

//import axios to call your backend.import axios from 'axios';

Let’s go to our componentDidMount and do a axios.get to our api/products endpoint. Which will retrieve the products. Make sure since it is a promise, we’ll have a resolve, and reject each will contain callbacks.

Resolve(.then), will have the response or res for short as an argument and reject(.catch) with the error or err for short as an argument. When it is rejected we catch the reason it was rejected, or handle the error. NOTE: FOR EACH .then YOU NEEED A .catch, it will give you issues when encountering errors.

axios.get('/api/products').then(res => {//Each .then must have a .catch to catch errors.}).catch(err => console.log('Read all products Error-------', err));

When debugging, console.log is your best friend. We’ll use it on our .catch to console log our identifier which can be anything, and the err itself. Because by the time we finish with app. We’ll have at least ten console.logs. So we need to identify a error if we encounter one.

Now what we will do next is in our resolved promise or within the callback for the .then. We will set the state of the products using this.setState({}), since state is immutable, we cannot use the assign operator(=).Then set it to the data from the response, and then set loading to false.

//always have console.logs for debuggingconsole.log('res.data products-----------', res.data);/////Set your loading to false, and products to the res.data, since we are doing res.send in our backend.this.setState({products: res.data, loading: false});

Great we are now retrieving the data. If you are encountering issues respond in the comments,and I will response quickly as possible.

Now we will go to our render method which will be responsible for rendering our html. Then we will destruct products, and loading from our state.We will return all products from the products array using p tags with the product name. Then import the it similar to how you imported the Navbar since they are in the same folder.

import Home from'./components/container/Home/Home';

Now if you run yarn start and nodemon it should return all products name. NOTE: You will have a key error in your console, that is irrelevant for now.

//Destruct the products, loading from state.const { products, loading } = this.state;return (<div className='home container'><div className='home-products container'>{/* If hte products have data return products else return nothing using terinary statement */}{products.length ? products.map(product => <p>{product.name}</p>) : null}</div></div>);
NOTE: I have a alot of sample data, make sure you create your sample data using postman post endpoint for our products.

Afterwards we’ll define an if statement, which will be if the loading state is false return the component else return the Loader Component which we will define next.

if(!loading) {
//Render Component
return ( <div className='home container'> <div className='home-products container'> {/* If hte products have data return products else return nothing using terinary statement */} {products.length ? products.map(product => <p>{product.name}</p>) : null} </div> </div> );} else {//Render Loader return <Loader />
}

Great let’s just to finish our render method off, we want a better and cleaner way of returning each product. We will use the ProductCard component to do that instead. Also instead of passing each property of the product we will give all of them via the spread operator(…). Also we will pass a key as the product.id to remove that key error in our console.

{/* If hte products have data return products else return nothing using terinary statement */}{products.length ? products.map(product => <ProductCard key={product.id} {...product} />) : null}

Now we just need to import them under our axios import, including our css file for styling.

//Import the ProductCard that will be responsible for rendering each product.import ProductCard from '../../presentational/ProductCard/ProductCard';//Import the loader that is used when the data is being retrievedimport Loader from '../../presentational/Loader/Loader';//import css file for stylingimport './Home.css';

Copy and paste this css to the Home.css

.home-products.container {margin: 10%;}

FInally!! We are done with the Home Component. It is giving you errors right now, which we handle when we define our presentational components.

Let’s define our presentational components, or components responsible for displaying data.

First define the Loader, then the ProductCard.

The Loader for now is just gonna be a stateless or functional component with the text of loading… . Stateless components does not have access to lifecycle methods so we are just gonna return the html. Don’t forget to import react and it’s corresponding css file.

import React from 'react';//Import csss file.import './Loader.css';const Loader = (props) => {return (<div className="loader-div"><h3>Loading......</h3></div>);};export default Loader;

Then copy and paste this to the Loader.css.

.loader-div {height: 100vh;width: 33%;display: grid;grid-template-rows: 33% 33% 33%;margin-left: auto;margin-right: auto;}.loader-div > * {grid-row: 2/2;font-size: 3em;}

Now lets finish this step off with our ProductCard component. With we will display each of the properties of the product except the id. First we will destruct the name, description, and price from the props. Then we will just simply display that data.

import React from 'react';//Import the css file for stylingimport './ProductCard.css';//Don't forget to pass props to a stateless component as a argument.const ProductCard = (props) => {const { name, price } = props;return (<div className='product-card container'><div><p className='product-card label'>{name}</p><p className='product-card label'>${price}</p></div></div>);};export default ProductCard;

Now let’s just import our css file for the ProductCard component.

.product-card.container {margin: 5%;border: solid 1px black;}.product-card.label {font-size: 2em;}

Now it should look like this.

Loading Screen:

While Retrieving Data.

When products are displayed.

When data is retrieved successfully.

Congrats you have basic frontend setup now.

Here is my github for reference .

Next we will setup our routing.

Happy Coding!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store