简体   繁体   中英

× TypeError: this.props.data.map is not a function

I have a React component that receives data, maps through it and prints out bootstrap cards containing the data in the objects that come through. However I have a problem that the data being returned is not allowing me to call .map (reporting an error TypeError: this.props.data.map is not a function ) even thought when I console.log the data it seems to be an array.

My code is below, as is the data shown in console.log. I've read other questions on SO and the general answer seems to be that the data is not an array - but mine seems to be.

I've tried it with converting the data to an array const data = Array.from(this.props.data); and then <CardDeck>{data.map(renderCard)}</CardDeck> and this gets me further, but then I get errors TypeError: Cannot read property '$numberDouble' of undefined which relates to areas in the data such as

 "manufacturer": "Panini",
"number": {
  "$numberDouble": "16"
},

can anyone advise what I am doing wrong here? I am getting the data from props, not from state - see image below

在此处输入图像描述

I can also print the data to the screen via

return (
      <Container>
        <h1>Hello {JSON.stringify(this.props.data)}</h1>
        {/* <CardDeck>{this.props.data.map(renderCard)}</CardDeck> */}
        {/* <CardDeck>{data.map(renderCard)}</CardDeck> */}
      </Container>
    );

在此处输入图像描述

Code

import React, { useState, useEffect } from "react";
import CardDeck from "react-bootstrap/CardDeck";
import Card from "react-bootstrap/Card";
import Col from "react-bootstrap/Col";
import Container from "react-bootstrap/Container";
import ListGroup from "react-bootstrap/ListGroup";
import ListGroupItem from "react-bootstrap/ListGroupItem";
import { Image, CloudinaryContext, Transformation } from "cloudinary-react";

class CardColumns extends React.Component {
  constructor(props) {
super(props);

this.state = {
  loading: "",
  error: "",
  data: null,
  username: "",
};
}

componentDidMount() {
this.props.loadCardData(this.props.path);
}

render() {
// const data = Array.from(this.props.data);
// const data = this.props.data;
console.log("HERE IS DATA " + JSON.stringify(this.props.data));
const renderCard = (card, index) => {
  return (
    // TODO: Looks at setting default heght (white space? on images so the last two classes below can be removed)
    <Col className="container-fluid mt-4 d-flex align-items-stretch">
      {/* <Card key={index} className="box"> */}
      <CloudinaryContext cloudName="dkwmxhsem">
        <Card
          style={{ width: "18rem" }}
          key={index}
          className="box h-100"
          border="danger"
        >
          <Card.Header>
            {card.brand} - {card.series}
          </Card.Header>
          <Card.Img
            variant="top"
            src={`${card.image_path}${card.card_id}.jpg`}
            fluid
          />

          <Card.Body>
            <Card.Title>
              {card.player} (#
              {card.card_number.$numberDouble}) {card.variation}
            </Card.Title>
          </Card.Body>
          <ListGroup className="list-group-flush">
            <ListGroupItem>
              <b>Print Run - </b>
              {card.print_run.$numberDouble}
            </ListGroupItem>
            <ListGroupItem>
              <b>Career Stage -</b> {card.career_stage}{" "}
            </ListGroupItem>
            <ListGroupItem>
              <b>For Trade -</b> {card.forTrade}
            </ListGroupItem>
          </ListGroup>
          <Card.Footer className="text-muted ">{card.team}</Card.Footer>
        </Card>
      </CloudinaryContext>
    </Col>
  );
};

return (
  <Container>
    <h1>Hello {this.props.num}</h1>
    <CardDeck>{this.props.data.map(renderCard)}</CardDeck>
  </Container>
);
}
}
export default CardColumns;

Output of console.log

[
  {
    "_id": {
      "$oid": "5f78532c82c81067eafdb896"
    },
    "card_id": "Was-Tre-2140",
    "brand": "National Treasures",
    "card_number": {
      "$numberDouble": "100"
    },
    "career_stage": "Veteran",
    "forTrade": "Yes",
    "image_path": "https://res.cloudinary.com/dkwmxhsem/image/upload/t_Card Resize/v1599758190/",
    "manufacturer": "Panini",
    "number": {
      "$numberDouble": "16"
    },
    "player": "Trent Williams",
    "print_run": {
      "$numberDouble": "25"
    },
    "purchase_date": "Thu Aug 20 00:00:00 GMT+01:00 2020",
    "series": "Century Materials",
    "status": "Own",
    "team": "Washington Football Team",
    "type": "Auto",
    "user": "jinsdvs@gmail.com",
    "variation": "Holo Silver",
    "year": "2010"
  },
  {
    "_id": {
      "$oid": "5f78532d82c81067eafdb906"
    },
    "card_id": "Was-Rya-6543",
    "brand": "Playbook",
    "card_number": {
      "$numberDouble": "85"
    },
    "career_stage": "Rookie Card",
    "forTrade": "",
    "image_path": "https://res.cloudinary.com/dkwmxhsem/image/upload/t_Card Resize/v1599758190/",
    "manufacturer": "Panini",
    "number": {
      "$numberDouble": "80"
    },
    "player": "Ryan Kerrigan",
    "print_run": {
      "$numberDouble": "299"
    },
    "purchase_date": "Tue Sep 01 00:00:00 GMT+01:00 2020",
    "series": "Rookie Signatures",
    "status": "Own",
    "team": "Washington Football Team",
    "type": "Auto",
    "user": "jsdvsdv@gmail.com",
    "variation": "Base",
    "year": "2011"
  }
]

try to initialize data as an empty array

this.state = { loading: "", error: "", data: [], username: "", }; } this.state = { loading: "", error: "", data: [], username: "", }; } i hope that will be helpful for you

First of all, initializing an array with null is not a good practice.

Rather try to initialize data with the type it is expected to be.

this.state = {
  loading: false,
  error: "",
  data: [],
  username: "",
};

Another thing is, that in modern JS (ECMA2020) you can prevent from getting an Cannot read property X of null.undefined simply by use of optional chaining .

<CardDeck>{this.props.data?.map(renderCard)}</CardDeck>

I think you're calling map in wrong way,did you try to display it as an arrow function this.state.data.map((renderCard) => renderCard)) ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM