尽管项目状态已用数据设置,但获取无法读取未定义的属性图
因此,我正在尝试使用 react 和 express 构建购物车。后端运行良好。我正在使用 postman 测试我的端点,它给了我正确的响应。然而,是 react 前端导致了问题。
我正在尝试在已设置为服务器响应的
items
数组上使用
map
函数,但它给了我一个错误:
TypeError: Cannot read property 'map' of undefined
这是我的代码:
Cart.js
import React, { Component } from "react";
import axios from "axios";
import CartItem from "./cart1-item.component.js";
import "bootstrap/dist/css/bootstrap.min.css";
import { throws } from "assert";
export default class Cart extends Component {
constructor(props) {
super(props);
this.state = {
items: []
};
}
componentDidMount() {
axios
.get("http://localhost:4000/cart/")
.then(response => {
this.setState({ items: response.data });
})
.catch(function(err) {
console.log(err);
});
}
checkItems() {
return this.state.items.items.map((currItem, i) => {
return <CartItem book={currItem} key={i}></CartItem>;
});
}
Calculate = item => {
return item.qty * item.price;
};
render() {
return (
<div className="container">
<div className="row">{this.checkItems()}</div>
</div>
);
}
}
CartItem.js
import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
const CartItem = props =>
props.items.map(item => {
return <div>{item.title}</div>;
});
export default CartItem;
以及邮递员对 '/cart' 的响应
{
"items": [
{
"item": "5dd7668f33c21d811b74f403",
"title": "Modern PHP",
"price": 25.65,
"qty": 1
}
],
"total": 25.65
}
这里也是 server.js 代码我不明白为什么当邮递员给我回复时我的数组是空的,这表明我的端点工作正常。
cartRoutes.route("/").get(function(req, res) {
var cart = req.session.cart;
var displayCart = { items: [], total: 0 };
var total = 0;
for (var item in cart) {
displayCart.items.push(cart[item]);
total += cart[item].qty * cart[item].price;
}
displayCart.total = total;
return res.json(displayCart);
});
cartRoutes.route("/:id").post(function(req, res) {
req.session.cart = req.session.cart || {};
var cart = req.session.cart;
let id = req.params.id;
Book.findById(id, function(err, book) {
if (err) {
console.log(err);
}
if (cart[id]) {
cart[id].qty++;
} else {
cart[id] = {
item: book._id,
title: book.title,
price: book.price,
qty: 1
};
}
res.redirect("/cart");
});
});
我已经花了一天半的时间试图自己解决这个问题。 任何帮助都将不胜感激。
由于另一个答案指出您的
initialState
不正确,因为您正在使用
checkItems
方法进行访问,所以您必须保留该结构。
我建议维护某些结构,在您的情况下,这看起来是您的
initialState
:
this.state = {
items: []
};
因此,当您调用方法
checkItems
时,您以错误的方式访问它:
checkItems() {
return this.state.items.items.map((currItem, i) => {
return <CartItem book={currItem} key={i}></CartItem>;
});
}
因此,据我所知,当您收到回复时,您正在修改
initialState
结构。
为了解决这个问题,我建议您进行以下小改动(只需将
response.data
更改为
response.data.items
):
componentDidMount() {
axios
.get("http://localhost:4000/cart/")
.then(response => {
this.setState({ items: response.data.items });
})
.catch(function(err) {
console.log(err);
});
}
以及方法
checkItems
:
checkItems() {
return this.state.items.map((currItem, i) => {
return <CartItem book={currItem} key={i}></CartItem>;
});
}
发生这种情况的原因是,当您加载应用程序时,您的初始状态是错误的。
this.state.items
是一个数组,但
this.state.items.items
是
undefined
,并且要使
.map()
函数正常工作,您需要一个数组。
因此,您的初始状态应如下所示:
this.state = {
items: {
items: []
}
};
似乎您的初始数据和来自 api 的数据的结构不匹配。您需要更改
checkItems
方法,并将嵌套的
items
设置为状态:
componentDidMount() {
axios
.get("http://localhost:4000/cart/")
.then(response => {
this.setState({ items: response.data.items }); // set items to the state
})
.catch(function(err) {
console.log(err);
});
}
checkItems() {
return this.state.items.map((currItem, i) => { // items is one level deep now
return <CartItem book={currItem} key={i}></CartItem>;
});
}
出现错误的原因是您的初始状态是
items: []
,这是第一次渲染所使用的状态。所以基本上在
checkItems
中,您试图访问一个空数组的
items
属性。
编辑:您还在子组件中访问了错误的 props,应该是
book
,而不是
items
,因为它是您传递的内容:
const CartItem = ({book}) => {
return <div>{book.title}</div>
}