Day #10 of #100daysofMiva. Hurray, what an important milestone in my 100daysofMiva coding challenge. See Day 10 project codes on GitHub.
I worked on a "Load More Data" project using React. This project involves fetching e-commerce product data from the dummyJSON API, displaying the products, and allowing the user to load more products incrementally by clicking a button
Code Breakdown and Analysis
1. Import Statements
javascript
import { useEffect, useState } from "react";
import "./styles.css";
useEffect
and useState
are React hooks that manage side effects and state within functional components.
./styles.css
imports the CSS file containing the styling for the component.
2. Component Definition
javascript
export default function LoadMoreData() {
const [loading, setLoading] = useState(false);
const [products, setProducts] = useState([]);
const [count, setCount] = useState(0);
const [disableButton, setDisableButton] = useState(false);
LoadMoreData
is a functional component that handles the data loading and rendering logic.
State Variables:
loading
: Manages the loading state, indicating whether data is currently being fetched.
products
: Holds the array of product data fetched from the API.
count
: Tracks the number of times the "Load More Products" button is clicked, which is used to calculate how much data to skip in the API call.
disableButton
: Disables the "Load More Products" button after a certain number of products have been loaded (100 in this case).
3. Fetching Products from the API
javascript
async function fetchProducts() {
try {
setLoading(true);
const response = await fetch(
`https://dummyjson.com/products?limit=10&skip=${count * 10}&select=title,price,thumbnail`
);
const result = await response.json();
if (result && result.products && result.products.length) {
setProducts((prevData) => [...prevData, ...result.products]);
setLoading(false);
}
console.log(result);
} catch (e) {
console.log(e);
setLoading(false);
}
}
fetchProducts
Function:
This function fetches product data from the dummyJSON API.
setLoading(true)
sets the loading state to true before making the API call.
The API endpoint is constructed dynamically using template literals. The limit parameter controls how many products to fetch at a time (10 products), and the skip parameter is calculated based on the count value to determine how many products to skip in the dataset.
select=title
,price
,thumbnail
specifies that only the title, price, and thumbnail image of each product should be returned.
If the response contains products, they are appended to the existing products in the products state using the spread operator (...), ensuring that previously loaded products are not overwritten.
The loading state is set to false after the data is fetched.
If an error occurs during the fetch, it is logged, and loading is stopped.
4. Effect Hooks for Fetching and Button Disable Logic
javascript
useEffect(() => {
fetchProducts();
}, [count]);
useEffect(() => {
if (products && products.length === 100) setDisableButton(true);
}, [products]);
useEffect
for Fetching Products:
The first useEffect
hook calls fetchProducts
whenever the count state changes. This ensures that every time the "Load More Products" button is clicked (and count is incremented), new products are fetched.
useEffect
for Disabling the Button:
The second useEffect
hook monitors the products array. When the length of products reaches 100, the disableButton
state is set to true, disabling the button to prevent further product loading.
5. Rendering the Component
javascript
if (loading) {
return <div>Loading data! Please wait.</div>;
}
Loading State:
If loading is true, the component renders a loading message, indicating that data is being fetched.
javascript
return (
<div className="load-more-container">
<div className="product-container">
{products && products.length
? products.map((item) => (
<div className="product" key={item.id}>
<img src={item.thumbnail} alt={item.title} />
<p>{item.title}</p>
</div>
))
: null}
</div>
<div className="button-container">
<button disabled={disableButton} onClick={() => setCount(count + 1)}>
Load More Products
</button>
{disableButton ? <p>You have reached 100 products</p> : null}
</div>
</div>
);
Product Display:
The products array is iterated over using the map function to render each product as a div containing an image and a title.
Load More Button:
A button is rendered to load more products. The disabled attribute is dynamically set based on the disableButton
state. Clicking the button increments the count state, triggering the fetching of more products.
Button Disable Message:
If the disableButton
state is true, a message is displayed informing the user that they have reached the maximum limit of 100 products.
Technicalities and Functionalities
State Management:
State is managed using the useState
hook. The loading, products, count, and disableButton
states handle different aspects of the component’s behavior.
Data Fetching:
The fetchProducts
function is responsible for communicating with the API, fetching the data, and updating the state accordingly.
Side Effects:
useEffect
hooks are used to perform side effects, like fetching data on initial render and when the count state changes, and disabling the button when the product limit is reached.
Conditional Rendering:
The component conditionally renders different UI elements based on the loading and disableButton
states, providing feedback to the user during data fetching and when the limit is reached.
Pagination Logic:
The count state effectively controls pagination by determining how many products to skip in the API request.
Performance Considerations:
By fetching and appending products in chunks, the application efficiently manages data, reducing the initial load time and spreading out the network requests.
How to Write Similar Functionality
To create a similar "Load More Data" functionality:
Set Up Initial State:
Use useState
to manage the states for loading, storing data, counting button clicks, and disabling the button.
Fetch Data:
Write an asynchronous function to fetch data from an API, handling any necessary parameters like limit and skip for pagination.
Manage Side Effects:
Use useEffect
to call the data-fetching function when the component first mounts or when a state that controls data fetching (like count) changes.
Render Conditionally:
Use conditional rendering to display loading messages, data, and disable buttons based on the current state.
Handle Button Clicks:
Attach an onClick
handler to a button that modifies the state controlling data fetching, triggering a new data fetch.
Style the Component:
Apply appropriate CSS to style the component, ensuring a user-friendly interface.
Top comments (0)