【问题标题】:Losing useState Value on Refresh in React.js在 React.js 中刷新时丢失 useState 值
【发布时间】:2022-01-25 00:27:15
【问题描述】:

我正在从ProductListing 组件发送id,并且我正在使用useParamsProductDetail 组件中接收id。在ProductDetail 组件中,我使用 find 方法查找对象,然后将其设置为singleProduct 状态。刷新时我得到 singleProduct 未定义。

进口

import React, { useState, useEffect } from "react";
import { NavLink, useParams } from "react-router-dom";
import Loading from "../other/Loading";

状态

const ProductDetail = () => {
  const [loading, setLoading] = useState(false);
  const [products, setProducts] = useState([]);
  const [singleProduct, setSingleProduct] = useState({});

使用 useParams 接收 id

  const { id } = useParams();

使用效果

  useEffect(() => {
   //GETTING PRODUCTS ARRAY
    getProductListingData();
   //FINDING A SINGLE OBJECT
    getProductID();
  }, []);

获取产品数组

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;

【问题讨论】:

    标签: javascript reactjs react-router react-router-dom


    【解决方案1】:
    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);
    };
    

    【讨论】:

    • 在获取数据列表后调用getProductID函数与产品参数
    【解决方案2】:

    这是正常行为,根据规范在刷新时重置状态。如果你想保存它,你需要使用 localStorage/sessionStorage/cookies 等。

    哪种方法最好?

    嗯,我会说第二种方法更好。我会避免将状态副本保存在本地存储中。我只会保留某种唯一标识用户并每次都获取新数据的令牌/ID(在您的情况下为 uid)。当您的应用程序增长时,可能很难在本地存储中管理这些状态。

    【讨论】:

      【解决方案3】:

      您不能使用 useState 钩子在页面刷新时保留数据,更好的方法是将该 id 作为 url 参数传递并检查 url 中是否有任何 id 然后获取产品。你的单页路由应该接受类似的参数。

      "/route/:id"
      

      您可以检查此代码 sn-p。 How to set and get route params in react

      【讨论】:

      • 请使用 little-state-machine,或者 redux-persit lib
      • 页面刷新 redux 状态也将被清除,直到您不使用 localStorage。?我还没有探索过小状态机。
      【解决方案4】:

      使用本地存储

      npm install reactjs-localstorage

      在您的项目中:

      import {reactLocalStorage} from 'reactjs-localstorage';
      

      随时随地设置和获取您的价值

      reactLocalStorage.set('var', true);
      reactLocalStorage.get('var', true);
      reactLocalStorage.setObject('var', {'test': 'test'});
      reactLocalStorage.getObject('var');
      reactLocalStorage.remove('var');
      reactLocalStorage.clear();
      

      来源: https://www.npmjs.com/package/reactjs-localstorage

      【讨论】:

        猜你喜欢
        • 2021-04-08
        • 1970-01-01
        • 1970-01-01
        • 2017-04-19
        • 2020-03-25
        • 2014-05-24
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多