Reputation:
I am sending an id
from ProductListing
Component and I am receiving that id
using useParams
in ProductDetail
Component. In ProductDetail
Component I am finding an object using find method and then I am setting it into singleProduct
state. On refresh I get singleProduct
is undefined.
imports
import React, { useState, useEffect } from "react";
import { NavLink, useParams } from "react-router-dom";
import Loading from "../other/Loading";
state
const ProductDetail = () => {
const [loading, setLoading] = useState(false);
const [products, setProducts] = useState([]);
const [singleProduct, setSingleProduct] = useState({});
receiving an id using useParams
const { id } = useParams();
useEffect
useEffect(() => {
//GETTING PRODUCTS ARRAY
getProductListingData();
//FINDING A SINGLE OBJECT
getProductID();
}, []);
getting products array
const getProductListingData = async () => {
try {
const response = await fetch("http://localhost:8000/productListing");
const data = await response.json();
if (data) {
setLoading(false);
setProducts(data.products);
} else {
setProducts("PRODUCT LISTING DATA NOT FOUND");
}
} catch (error) {
console.log(error);
}
};
if (loading) {
return <Loading loadingProductListing="Loading Product List" />;
}
const getProductID = () => {
let foundProduct = {};
foundProduct = products.find((item) => {
return item.id === parseInt(id);
});
setSingleProduct(foundProduct);
};
// console.log("product ID = ", productID, typeof productID);
console.log("products = ", products);
console.log("singleproduct = ", singleProduct);
JSX
return (
<>
<div className="dvProducts col-12">
<div className="row">
<div className="col-12">
<NavLink
to="/product-listing"
className="text-dark mb-1 d-inline-block"
>
<i className="fa fa-angle-left f16"></i>
<span> Back</span>
</NavLink>
</div>
<div className="col-12 col-md-6 col-xl-4 mb-3">
<div className="border border-light shadow-sm p-1 h-100">
<div className="bg-light text-center p-5">
<a className="d-inline-block">
<img
src="images/description/coconut-water-200ml.png"
className="img-fluid"
alt="..."
/>
</a>
</div>
</div>
</div>
<div className="col-12 col-md-6 col-xl-8 d-flex mb-3 mb-xl-0">
<div className="m-md-auto">
<div>
<h4>Coconut Water</h4>
</div>
<div className="mb-2">
<i className="fa fa-star text-warning d-inline-block"></i>
<i className="fa fa-star text-warning d-inline-block"></i>
<i className="fa fa-star text-warning d-inline-block"></i>
<i className="fa fa-star-o text-warning d-inline-block"></i>
<i className="fa fa-star-o text-warning d-inline-block"></i>
</div>
<div className="mb-3">
<p>
Every athlete's go to natural energy drink; Coconut
Water is a complete win-win for your everyday
rehydration needs. #iaminlovewiththecoco!
</p>
</div>
<div className="d-flex mb-3">
<div className="mr-2">
<h6 className="d-inline-block mb-1">Size:</h6>
<span className="d-inline-block">200ml</span>
</div>
<div className="mr-2 ml-2">
<h6 className="d-inline-block mb-1">Category:</h6>
<span className="d-inline-block">Juices</span>
</div>
<div className="ml-2">
<h6 className="d-inline-block mb-1">Price:</h6>
<span className="d-inline-block">
<i className="fa fa-inr"></i>
<span className="d-inline-block">40.00</span>
</span>
</div>
</div>
<div>
<button
className="btn btnSecondary"
href="detail.html"
>
Add to Bag
</button>
</div>
</div>
</div>
</div>
</div>
</>
);
};
export default ProductDetail;
Upvotes: 7
Views: 20490
Reputation: 96
use localstorage
npm install reactjs-localstorage
in your project :
import {reactLocalStorage} from 'reactjs-localstorage';
set and get your value everywhere you want
reactLocalStorage.set('var', true);
reactLocalStorage.get('var', true);
reactLocalStorage.setObject('var', {'test': 'test'});
reactLocalStorage.getObject('var');
reactLocalStorage.remove('var');
reactLocalStorage.clear();
source : https://www.npmjs.com/package/reactjs-localstorage
Upvotes: 1
Reputation: 51
You can't persist the data on page refresh with useState hook, better way is to pass that id as url params and check if there is any id in url then fetch the product. your single page route should accept a param like.
"/route/:id"
You can check this code snippet. How to set and get route params in react
Upvotes: 1
Reputation: 91
const getProductListingData = async () => {
try {
const response = await fetch("http://localhost:8000/productListing");
const data = await response.json();
if (data) {
setLoading(false);
setProducts(data.products);
// call this function after you are getting list of products
getProductID(data.products);
} else {
setProducts("PRODUCT LISTING DATA NOT FOUND");
}
} catch (error) {
console.log(error);
}
};
const getProductID = (tempProducts) => {
let foundProduct = {};
foundProduct = tempProducts.find((item) => {
return item.id === parseInt(id);
});
setSingleProduct(foundProduct);
};
Upvotes: 2
Reputation: 6749
That's a normal behaviour, state is being reset on refresh per specification. If you want to preserve it you need to make use of localStorage/sessionStorage/cookies etc.
Which is best way?
Well I would say that the second approach is better. I would avoid keeping copy of state in localstorage. I would only keep some kind of token/id (in your case uid) which uniquely identify the user and would fetch fresh data every time. When your application grows it can be hard to manage those states in localstorage.
Upvotes: 5