开发者问题收集

尽管项目状态已用数据设置,但获取无法读取未定义的属性图

2019-11-25
68

因此,我正在尝试使用 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");
  });
});

我已经花了一天半的时间试图自己解决这个问题。 任何帮助都将不胜感激。

3个回答

由于另一个答案指出您的 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>;
    });
  }
Ricardo Gonzalez
2019-11-25

发生这种情况的原因是,当您加载应用程序时,您的初始状态是错误的。 this.state.items 是一个数组,但 this.state.items.itemsundefined ,并且要使 .map() 函数正常工作,您需要一个数组。 因此,您的初始状态应如下所示:

this.state = {
  items: {
    items: []
  }
};
dw_
2019-11-25

似乎您的初始数据和来自 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> 
}
Clarity
2019-11-25