如果在 React 中卸载时添加检查,则不会渲染产品

问题描述 投票:0回答:1

在我的应用程序中,我正在实现产品列表页面,该页面列出了列表页面上的产品。我希望基于这篇文章整合一些好的实践 - https://dev.to/vyan/using-async-functions-in-useeffect-best-practices-and-pitfalls-o75 但不是

let
我正在使用
ref
进行跟踪。

我在控制台消息中获取产品列表,但它在 UI 中不显示任何列表。当我在清理函数中注释 -

isMounted.current = false;
行时,只有它显示列表。让我知道我在清理过程中做错了什么?

App.jsx -

import { useEffect, useRef, useState } from "react";
import ProductsList from "./components/ProductsList";
import "./styles.css";

export default function App() {
  const isMounted = useRef(true);
  const [products, setProducts] = useState([]);

  const fetchData = async () => {
    try {
      const data = await fetch("https://dummyjson.com/products");
      const { products = [] } = await data.json();
      console.log(products); // It shown as Array of object in the console

      if (isMounted.current) {
        setProducts(products);
      }
    } catch (error) {
      if (isMounted.current) {
        console.error("Error fetching data: ", error);
      }
    }
  };

  useEffect(() => {
    fetchData();
    return () => {
      isMounted.current = false; // Cleanup on unmount
    };
  }, []);

  return (
    <div className="App">
      <h1>Product Listing Page</h1>
      {products.length ? <ProductsList products={products} /> : null}
    </div>
  );
}

ProductsList.jsx -

const ProductsList = ({ products }) => {
  return (
    <div className="products-list">
      {products.map((product) => {
        return (
          <div className="product" key={product.id}>
            <div className="max-w-sm rounded overflow-hidden shadow-lg">
              <img
                className="w-full"
                src={product.thumbnail}
                alt={product.thumbnail}
              />
              <div className="px-6 py-4">
                <div className="font-bold text-xl mb-2">{product.title}</div>
                <p className="text-gray-700 text-base">{product.description}</p>
              </div>
              <div className="px-6 pt-4 pb-2">
                {product.tags.map((tag, index) => (
                  <span
                    key={index}
                    className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2"
                  >
                    #{tag}
                  </span>
                ))}
              </div>
            </div>
          </div>
        );
      })}
    </div>
  );
};

export default ProductsList;
javascript reactjs react-hooks async-await
1个回答
0
投票

在 React Strict 模式下,React 调用效果设置和清理函数(模拟挂载/卸载)。因此,当第二次重新调用 setup 函数时,在 cleanup 函数中更新的 ref 值仍将被设置为

false
(请参阅 此讨论,了解这是否是预期行为)。

React 团队不鼓励使用引用来检测安装,并且建议也使用变量(如您的文章中提到的那样)来确定组件是否已卸载。

如果必须使用引用,则可以在初始安装时将引用重置为

true
(本质上“撤消”严格模式清理调用的影响):

useEffect(() => {
  isMounted.current = true;
  fetchData();
  return () => {
    isMounted.current = false; // Cleanup on unmount
  };
}, []);

但是,我建议您尝试使用文档中建议的变量方法来避免这种模式。

© www.soinside.com 2019 - 2024. All rights reserved.