This is an e-commerce website.
<Route path='products/:productId' element={<Product />} />
Here I am using react dynamic route for showing product’s details when clicked on a product.
I have a ShopContext.jsx file which gets all the products from the server and provides to the other components when needed. Here is the part of that code in my ShopContext.jsx file:
const [all_product, setAll_Product] = useState([]);
useEffect(() => {
fetch(`${process.env.REACT_APP_SERVER_API}/allproducts`)
.then((res) => res.json())
.then((data) => setAll_Product(data));
....
}, [])
This one below is my main product page:
const Product = () => {
const {all_product} = useContext(ShopContext);
const {productId} = useParams();
const product = all_product.find((e)=> e.id === Number(productId))
return (
<div>
<ProductDisplay product = {product}/>
<DescriptionBox/>
<RelatedItems/>
</div>
)
}
export default Product;
It passes the ‘product’ to the product display component and the product display component renders that .
but when i refresh the page the ‘product’ param becomes undefined. it says, “product is undefined”. why? and how to solve this?
Edit: Here is the full shop context file:
mport React, { createContext, useEffect, useState } from "react";
export const ShopContext = createContext(null);
const getDefaultCart = ()=>{
let cart = {};
for(let i = 0; i < 300 + 1; i++) {
cart[i] = 0;
}
return cart;
}
const ShopContextProvider = (props) => {
const [all_product, setAll_Product] = useState([]);
const [cartItems, setCartItems] = useState(getDefaultCart());
useEffect(() => {
fetch(`${process.env.REACT_APP_SERVER_API}/allproducts`)
.then((res) => res.json())
.then((data) => setAll_Product(data));
console.log("context "+all_product);
if(localStorage.getItem('auth-token')) {
fetch(`${process.env.REACT_APP_SERVER_API}/getcart`, {
method: 'POST',
headers: {
Accept: 'application/form-data',
'auth-token': `${localStorage.getItem('auth-token')}`,
'content-type': 'application/json'
},
body: ""
})
.then((res) => res.json())
.then((data) => setCartItems(data));
}
}, [])
const addToCart = (itemId) => {
setCartItems((previous) => ({...previous,[itemId]:previous[itemId] + 1}));
if(localStorage.getItem('auth-token')) {
fetch(`${process.env.REACT_APP_SERVER_API}/addtocart`, {
method: "POST",
headers: {
Accept: "application/form-data",
'auth-token': `${localStorage.getItem('auth-token')}`,
'content-type': "application/json",
},
body: JSON.stringify({"itemId" : itemId})
})
.then((res) => res.json())
.then((data) => console.log(data));
}
}
const removeFromCart = (itemId) => {
setCartItems((previous) => ({...previous,[itemId]:previous[itemId] - 1}));
if(localStorage.getItem('auth-token')) {
fetch(`${process.env.REACT_APP_SERVER_API}/removefromcart`, {
method: "POST",
headers: {
Accept: "application/form-data",
'auth-token': `${localStorage.getItem('auth-token')}`,
'content-type': "application/json",
},
body: JSON.stringify({"itemId" : itemId})
})
.then((res) => res.json())
.then((data) => console.log(data));
}
}
const deleteFromCart = (itemId) => {
setCartItems((previous) => ({...previous,[itemId]:0}));
if(localStorage.getItem('auth-token')) {
fetch(`${process.env.REACT_APP_SERVER_API}/deletefromcart`, {
method: "POST",
headers: {
Accept: "application/form-data",
'auth-token': `${localStorage.getItem('auth-token')}`,
'content-type': "application/json",
},
body: JSON.stringify({"itemId" : itemId})
})
.then((res) => res.json())
.then((data) => console.log(data));
}
}
const getTotalCartAmount = () => {
let totalAmount = 0;
for(const item in cartItems) {
if(cartItems[item] > 0) {
let itemInfo = all_product.find((product) => product.id === Number(item));
totalAmount += itemInfo.new_price * cartItems[item];
}
}
return totalAmount;
}
const getTotalCartItems = () => {
let totalItems = 0;
for(const item in cartItems) {
if(cartItems[item] > 0) {
totalItems += cartItems[item];
}
}
return totalItems;
}
const contextValue = {all_product, cartItems, addToCart, removeFromCart, deleteFromCart, getTotalCartAmount, getTotalCartItems};
return (
<ShopContext.Provider value = {contextValue}>
{props.children}
</ShopContext.Provider>
)
}
export default ShopContextProvider;