首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >useFetch自定义钩子不能正常工作

useFetch自定义钩子不能正常工作
EN

Stack Overflow用户
提问于 2021-11-18 05:21:53
回答 1查看 603关注 0票数 1

我正在工作的反应网站。我已经创建了一个自定义数据获取钩子'usePostFetch‘,如下所示:

代码语言:javascript
复制
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。

产品页:

代码语言:javascript
复制
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;

但是当我进入这个链接时,我在控制台中得到了这样的数据:

由于这些空数组,我得到了如下错误:

我能做什么,或者我的代码有什么问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-18 05:29:07

似乎您正在读取尚不存在的状态。初始的data状态是一个空对象:

代码语言:javascript
复制
const [data, setData] = useState({});

在初始呈现时,您正在尝试从0属性中读取,该属性仍未定义。

代码语言:javascript
复制
data[0] --> OK, undefined
data[0].productName --> NOT OK, throws error trying to access from undefined

当您知道data内容已填充时,您可以有条件地呈现它:

代码语言:javascript
复制
<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>

也可以只使用可选的链接运算符来抵御空/未定义的属性访问:

代码语言:javascript
复制
<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是一个数组,因此您希望您的初始状态保持状态/类型不变,因此也应该将其声明为数组。

代码语言:javascript
复制
const [data, setData] = useState([]);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70014925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档