[英]Losing useState Value on Refresh in React.js
I am sending an id
from ProductListing
Component and I am receiving that id
using useParams
in ProductDetail
Component.我正在从ProductListing
组件发送一个id
,并且我正在使用ProductDetail
组件中的useParams
接收该id
。 In ProductDetail
Component I am finding an object using find method and then I am setting it into singleProduct
state.在ProductDetail
组件中,我使用 find 方法找到了 object,然后将其设置为singleProduct
state。 On refresh I get singleProduct
is undefined.刷新时我得到singleProduct
未定义。
imports进口
import React, { useState, useEffect } from "react";
import { NavLink, useParams } from "react-router-dom";
import Loading from "../other/Loading";
state state
const ProductDetail = () => {
const [loading, setLoading] = useState(false);
const [products, setProducts] = useState([]);
const [singleProduct, setSingleProduct] = useState({});
receiving an id using useParams使用 useParams 接收 id
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 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;
That's a normal behaviour, state is being reset on refresh per specification.这是正常行为,state 正在按照规范在刷新时重置。 If you want to preserve it you need to make use of localStorage/sessionStorage/cookies etc.如果你想保存它,你需要使用 localStorage/sessionStorage/cookies 等。
Which is best way?哪个是最好的方法?
Well I would say that the second approach is better.好吧,我会说第二种方法更好。 I would avoid keeping copy of state in localstorage.我会避免在本地存储中保留 state 的副本。 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.我只会保留某种令牌/ID(在您的情况下为 uid),它唯一地标识用户并且每次都会获取新数据。 When your application grows it can be hard to manage those states in localstorage.当您的应用程序增长时,可能很难在本地存储中管理这些状态。
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);
};
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.您不能使用 useState 挂钩在页面刷新时保留数据,更好的方法是将该 id 作为 url 参数传递,并检查 url 中是否有任何 id 然后获取产品。 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 如何在反应中设置和获取路由参数
use localstorage使用本地存储
npm install reactjs-localstorage npm 安装 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来源: https://www.npmjs.com/package/reactjs-localstorage
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.