我在 React 網站上作業。我創建了一個自定義資料獲取掛鉤“ usePostFetch ”,如下所示:
import React, { useState, useEffect } from "react";
//axios
import axios from "axios";
const usePostFetch = () => {
const [postData, setPostData] = useState([]);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const getData = async () => {
setIsLoading(true);
try {
const res = await axios.get("http://localhost:8000/Sell");
const data = await res.data;
setPostData(data);
setIsLoading(false);
} catch (error) {
console.log("Error from fetch: " error);
setError(error.message);
setIsLoading(false);
}
};
getData();
}, []);
const values = [
...new Set(
postData.map((post) => {
return post.productType;
})
),
];
return { postData, values, error, isLoading };
};
export default usePostFetch;
我有一個產品頁面,當我單擊主頁上帶有鏈接“ /product/:productId ”的任何鏈接時會呈現該頁面。productId 是單擊的鏈接產品的 ID。
產品頁面:
import React, { useEffect, useState } from "react";
//react router dom
import { useParams } from "react-router";
//Hooks
import usePostFetch from "../../Hooks/usePostFetch";
//styles
import { Wrapper, Info, Discription } from "./Product.styles";
//Server
const Server = "http://localhost:8000";
const Product = () => {
const { productId } = useParams();
const { postData, isLoading, error } = usePostFetch();
const [data, setData] = useState({});
console.log(postData, isLoading, error);
useEffect( () => {
const fetchData = async () => {
var value = await postData.filter((post) => {
return post._id === productId;
});
console.log(value);
setData(value);
};
fetchData();
}, [postData]);
return (
<Wrapper>
<Info>
{isLoading && <h1> Loading.... </h1>}
{error && <p>ERROR </p>}
{console.log(data)}
<img
src={`${Server}/productImages/${data[0].productImage}`}
alt={`${data[0].productName}`}
/>
<div className="data">
<h1>{data[0].productName}</h1>
<h3>{data[0].productPrice}</h3>
</div>
</Info>
</Wrapper>
);
};
export default Product;
但是當我轉到那個鏈接時,我在控制臺中得到了這樣的資料: 這是控制臺影像
由于這些空陣列,我得到了這樣的錯誤: 頁面影像
我能做什么或我的代碼有什么問題?
uj5u.com熱心網友回復:
看來您正在閱讀尚不存在的狀態。初始data狀態是一個空物件:
const [data, setData] = useState({});
并且在初始渲染時,您試圖從一個0屬性中讀取,OFC 仍然是未定義的。
data[0] --> OK, undefined
data[0].productName --> NOT OK, throws error trying to access from undefined
data當您知道內容已填充時,您可以有條件地呈現內容:
<Wrapper>
<Info>
{isLoading && <h1> Loading.... </h1>}
{error && <p>ERROR </p>}
{console.log(data)}
{data[0] && (
<img
src={`${Server}/productImages/${data[0].productImage}`}
alt={`${data[0].productName}`}
/>
<div className="data">
<h1>{data[0].productName}</h1>
<h3>{data[0].productPrice}</h3>
</div>
)
</Info>
</Wrapper>
或者,您可以僅使用 Optional Chaining 運算子來防御空/未定義的屬性訪問:
<Wrapper>
<Info>
{isLoading && <h1> Loading.... </h1>}
{error && <p>ERROR </p>}
{console.log(data)}
<img
src={`${Server}/productImages/${data[0]?.productImage}`}
alt={`${data[0]?.productName}`}
/>
<div className="data">
<h1>{data[0]?.productName}</h1>
<h3>{data[0]?.productPrice}</h3>
</div>
</Info>
</Wrapper>
看起來你真的希望data成為一個陣列,所以你會希望你的初始狀態保持狀態/型別不變,所以它也應該宣告為一個陣列。
const [data, setData] = useState([]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/359536.html
標籤:javascript 反应 反应钩子
