React JS Create Shop Page with Skeleton Loading
Most of today’s modern interactive apps load data from the background and the data to be loaded will take some time as the server needs to send the data.
Till then the app must wait till the data is displayed. And in-between of these processes it can developers would display a circular loading which let
users know that the data is loading and they would wait.
These designs bother most of the frontend and UI/UX developers and then they changed it by using a dummy screen which acts as a placeholder for the layout of the actual
element. This looks more intuitive and effective as users may know that the data will load soon.
In this Product, I’ll show how you can easily create a skeleton in React JS. I’ll be taking an example of a shop page where I’ll load products after the page is loaded.
Watch Video
Installation
Start by installing package react-content-loader which creates SVG Placeholders.
npm i react-content-loader --save
Preparing Loaders
In src\components\loaders\product-loader.js
import React from 'react' import ContentLoader from "react-content-loader" export default function ProductLoader( props ) { const count = ( props.count )? parseInt(props.count) : 1 return ( <> { [...Array(count)].map( ( item, index ) => { return ( <ContentLoader key={index} viewBox="0 0 500 420" height={400} width={500} {...props}> <rect x="16" y="17" rx="0" ry="0" width="360" height="200" /> <circle cx="35" cy="248" r="20" /> <rect x="69" y="229" rx="2" ry="2" width="275" height="15" /> <rect x="69" y="253" rx="2" ry="2" width="140" height="15" /> </ContentLoader> ) } ) } </> ) }
The ProductLoader
the component will load the skeleton and there is a count
variable that will load multiple of such placeholders.
Recommended
The loaders templates are available in skeletonreact. Just copy the code and add it to the component to reduce development time.
Design Product Card Component
In src\components\product-card.js
import React from 'react' import styles from 'components/product-card.module.css' export default function ProductCard( { product, ...props } ) { return ( <div className={styles['product-card']} > <div className={styles['product-card-header']} > <div className={styles['product-card-image-wrapper']} > <img src={product.image} className={styles['product-card-image']} alt="" /> </div> <div> <p className={styles['product-card-title']} >{product.title}</p> </div> </div> <div className={styles['product-card-body']} > <img src={product.image} className={styles['product-card-body-image']} alt="" /> </div> </div> ) }
The component ProductCard
return a single card element. We have to loop over each one of them to display multiple of them.
Styling Product Card Component
In src\components\product-card.module.css
.product-card{ border: 1px solid #ccc; margin: 5px 0; } .product-card-image-wrapper{ display: flex; align-items: center; } .product-card-image{ width: 50px; height: 50px; border-radius: 50%; border: 3px solid #eee; } .product-card-body-image{ width: 100%; height: 150px; object-fit: contain; } .product-card-header{ display : flex; gap:10px; border-bottom: 1px solid #ccc; padding: 3px 5px; } .product-card-body{ padding: 10px 5px; } .product-card-body p{ margin: 0; }
Loading Skeleton in Shop Page
In src\App.js
import React, { useEffect, useState } from 'react' import styles from './App.module.css' import ProductLoader from 'components/loaders/product-loader' import ProductCard from 'components/product-card' function App() { const [products, setProducts] = useState([]) useEffect( ()=>{ init() }, [] ) const init = async()=>{ let res = await fetch( "https://fakestoreapi.com/products" ) res = await res.json() setProducts([...res]) } return ( <> <div className={styles['container']} > <div> <h4 style={{textAlign:'center'}} >Shop</h4> </div> <div className={styles['product-items-container']} > { ( products.length ) ? products.map( ( item, index ) => { return ( <ProductCard key={index} product={item} /> ) } ) : ( <ProductLoader count={5} /> ) } </div> </div> </> ); } export default App;
We have declared [products, setProducts]
as states and while rendering if they products
are empty then we’ll display ProductLoader
components.
The function init()
will be invoked after the page is loaded which fetches the products and updates products
state.
In src\App.module.css
.container{ width: 80%; margin: auto; } .product-items-container{ width: 400px; margin: auto; }
Here we are doing basic styling for alignment purpose.
Next include App
in index.js
In src\index.js
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
Output

Final Output Of React Js Skeleton Loading for displaying products on shop page
Sandbox
Find code to Github Repository