Javascript 为什么可以';t我访问从express中的API获取的JSON对象的子属性
我正试图通过React Hooks将一个名为products的对象从我用express创建的一个简单API带到我使用Axios的前端,显然,只要我不尝试访问主对象中对象内部的属性,一切都可以正常工作,因为当我尝试此操作时,React会抛出以下错误: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.
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...</>;
}