Javascript 为什么可以';t我访问从express中的API获取的JSON对象的子属性

Javascript 为什么可以';t我访问从express中的API获取的JSON对象的子属性,javascript,reactjs,express,react-hooks,mern,Javascript,Reactjs,Express,React Hooks,Mern,我正试图通过React Hooks将一个名为products的对象从我用express创建的一个简单API带到我使用Axios的前端,显然,只要我不尝试访问主对象中对象内部的属性,一切都可以正常工作,因为当我尝试此操作时,React会抛出以下错误: TypeError: Cannot read property '0' of undefined ProductScreen src/screens/ProductScreen.js:40 37 | text={`${product.

我正试图通过React Hooks将一个名为products的对象从我用express创建的一个简单API带到我使用Axios的前端,显然,只要我不尝试访问主对象中对象内部的属性,一切都可以正常工作,因为当我尝试此操作时,React会抛出以下错误:

TypeError: Cannot read property '0' of undefined

ProductScreen
src/screens/ProductScreen.js:40

  37 |     text={`${product.numReviews} reviews`}
  38 |   />
  39 | </ListGroup.Item>
> 40 | <ListGroup.Item>Precio: ${product.type[0].price}</ListGroup.Item>
     | ^  41 | <ListGroup.Item>
  42 |   Descripción: <br /> {product.description}
  43 | </ListGroup.Item>

View compiled

▶ 16 stack frames were collapsed.
在产品变量中保存JSON对象


我认为问题的一个关键点是,如果我在browser developer tools中进入网络,fetch对象的标题会给出:

 - Content-Type: text/html; charset = UTF-8 
 - Status Code: 200 
 - Response:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="El sabor del norte a tu casa" />
    <link rel="apple-touch-icon" href="/logo192.png" />
    <link rel="manifest" href="/manifest.json" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"
      integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA=="
      crossorigin="anonymous"
    />
    <title>Bienvenido a Grill Shop</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  <script src="/static/js/bundle.js"></script><script src="/static/js/0.chunk.js"></script><script src="/static/js/main.chunk.js"></script><script src="/main.c767f2926d55ce283409.hot-update.js"></script></body>
</html>
下图显示了我从后端得到的响应:

如您所见,我的API在端口5000上运行,而我的前端在端口3000上运行。在我的前端配置文件中,我添加了一个指向端口5000的代理,以便能够访问后端服务


我提前向您表示感谢,因为我花了几天时间试图解决这个问题,但我没有找到解决方案

您在查询后端时没有告诉前端使用端口5000

这一行:

const product = await axios.get(`/api/products/${match.params.id}`)
将执行对来自同一主机(localhost:3000)的请求,因此整个url将为:

http://localhost:3000/api/products/${match.params.id}

只需设置适当的主机,您就可以:

const product = await axios.get(BASE_URL + `/api/products/${match.params.id}`)

其中
BASE\u URL
应该是一个全局常量,您可以根据部署后端的位置进行相应更改,在本地计算机上开发时,应该是
http://localhost:5000

使用空对象作为默认值(
useState({})
)。当组件挂载时,它将发送您的网络请求,但是响应需要一些时间。在此期间,默认参数
{}
用作
产品
。因此,
product.type
和您访问的所有其他属性将返回
未定义的

使用React时,必须始终明确说明要渲染的内容,即使这意味着不应渲染任何内容

一个简单的解决方案是使用默认值
null
,并且只在
产品
真实时渲染某些内容

const [product, setProduct] = useState(null);

useEffect(() => {
  const fetchProduct = async () => {
    const product = await axios.get(`/api/products/${match.params.id}`);
    setProduct(product.data);
  };

  fetchProduct();
}, [match]);

// render nothing during the time product is loading
if (!product) return null;

return <>render product</>;

似乎没有解决任何问题,相反,没有给我带来任何数据。这就是为什么我要使用端口5000的代理,我想是的。呈现组件时浏览器中显示的错误已经修复,但仍然无法访问JSON对象的子属性,并且正在获取html/文本内容类型,而不是get请求中的JSON。知道为什么会这样吗?谢谢你的帮助@JJS_Vegu在使用axios获取响应后,您是否已经通过放置
console.log(product.data)
来检查响应是什么?现在它似乎可以工作了!由于某种原因,我以前没看到它起作用。谢谢
// assuming you use null as default
if (product) {
  // product is loaded
  return <>render product</>;
} else {
  // product is loading
  return <>loading...</>;
}