簡體   English   中英

如何將數據傳輸到另一個組件(useEffect 問題)

[英]how can I transfer the data to another component (useEffect problem)

在 useEffect 中,我從服務器檢索數據並將其存儲在“products”數組中:

const { url } = props;
const [products, setProducts] = useState([]);

  useEffect(() => {
    const fetchProducts = async () => {
      setLoadingSpinner(true);
      const response = await fetch(url);
      const responseData = await response.json();
      setLoadingSpinner(false);
      const loadedProducts = [];

      for (const key in responseData) {
        loadedProducts.push({
          id: key,
          name: responseData[key].name,
          description: responseData[key].description,
          price: responseData[key].price,
          image: responseData[key].image,
          processor: responseData[key].processor,
        });
      }
      setProducts(loadedProducts);
      setIsDataLoaded(true);
    };
    fetchProducts();
  }, [url, isDataLoaded]);

我將它傳遞給 ProductDetail 組件:

<ProductDetail products={products}></ProductDetail>

我總是在 ProductDetail 組件中得到一個 null 值:

function ProductDetail(props) {
    const params = useParams();
    const [product, setProduct] = useState(null);
    
    useEffect(() => {
      if (props.products && params.productId) {
        const product = props.products.find(product => product.id === params.productId);
        setProduct(product);
      }
    }, [props.products, params.productId]);

    console.log(product)

我意識到當 useEffect 第一次運行時,我的“products”數組仍然是空的,它會將它發送到組件,所以這並不好。 但我不知道如何解決這個問題。

這里有一些錯誤。 我將從一開始看起來切線的東西開始,但它會導致更好的答案。

ProductDetail中,您引入了一個名為product的新 state。 然后,在useEffect中,從 props 中的列表和產品 ID 中找到產品,並將其設置回 state 項目。 這將是不必要的 state 重復(即使沒有將 prop 逐字復制到 state,直接從 props 派生的值仍然很重要)並且會增加應用程序中錯誤的表面積(這可能是最常見的初學者錯誤)。

你實際上不需要那個 state 項目,你只需要useMemo

function ProductDetail(props) {
    const params = useParams();
    
    const product = useMemo(() => {
      if (props.products && params.productId) {
        return props.products.find(product => product.id === params.productId);
      }
    }, [props.products, params.productId]);

    console.log(product)

要解決在加載產品時暫時找不到產品的問題,您可以 (a) 有條件地呈現組件,這樣當尚未獲取products時,此代碼甚至不會首先運行。 或者 (b) 更改ProductDetail ,使其在找到產品之前什么都不做。

溶液A

const [products, setProducts] = useState(null); // We change the default to null to be able to distinguish empty list case from loading case.

// ...

{products !== null && <ProductDetail products={products}></ProductDetail>}

溶液B

function ProductDetail(props) {
    const params = useParams();
    
    const product = useMemo(() => {
      if (props.products && params.productId) {
        return props.products.find(product => product.id === params.productId);
      }
    }, [props.products, params.productId]);

    if (!product) return null // Return early (do nothing) whilst product is not found

    // ... your original render contents

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM