Pedro
Pedro

Reputation: 125

how to display information by props from an array of objects in a component in React JS

I have two files, ListCurses and CardCurses, in the ListCurses a have an array of objects and I'm trying to run it and display the information in another component (CardCurses) by props, but the page returns this error message " TypeError: Cannot read property 'props' of undefined ". If anyone can help me I will be grateful, thanks !

CardCurses.jsx

import React, { Component } from "react";
import { Card } from "antd";

const { Meta } = Card;

function CardCurses() {
   return (
     <Card
        hoverable
        style={{ width: 200, height: 240, padding: "10px" }}
        cover={<img alt="example" src={this.props.text.image} />}
     >
        <Meta
           title={this.props.text.title}
           description={this.props.text.descricao}
        />
     </Card>
  );
}

export default CardCurses;

ListCurses

import React from "react";
import Card from "../CardCurses/CardCurses";

function ListCurses() {
   const cursos = [
    {
      title: "React JS",
      descricao: "React é legal",
      image: "https://pt-br.reactjs.org/logo-og.png"
    },
    {
      title: "React Native",
      descricao: "React Native é legal",
      image: "https://miro.medium.com/max/1000/1*GkR93AAlILkmE_3QQf88Ug.png"
    },
    {
      title: "Antd",
      descricao: "Antd é legal",
      image: "https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg"
    }
  ];

  const returnCurses = cursos.map((curse, i) => {
  return (
      <div key={i}>
        <Card text={curse} />
      </div>
    );
  });
  return <div>{returnCurses}</div>;
}


export default ListCurses;

Upvotes: 1

Views: 59

Answers (1)

Izhaki
Izhaki

Reputation: 23586

You haven't defined any props here:

function CardCurses() { ... }

You need:

function CardCurses(props) { ... }

Also, you are mixing function and class components. Function component have no this. So:

function CardCurses(props) {
   return (
     <Card
        hoverable
        style={{ width: 200, height: 240, padding: "10px" }}
        cover={<img alt="example" src={props.text.image} />}
     >
        <Meta
           title={props.text.title}
           description={props.text.descricao}
        />
     </Card>
  );
}

Or:

const CardCurses = ({ text }) => (
  <Card
    hoverable
    style={{ width: 200, height: 240, padding: '10px' }}
    cover={<img alt="example" src={text.image} />}>
    <Meta title={text.title} description={text.descricao} />
  </Card>
);

Or:

const CardCurses = ({ text: { image, title, descricao} }) => (
  <Card
    hoverable
    style={{ width: 200, height: 240, padding: '10px' }}
    cover={<img alt="example" src={image} />}>
    <Meta title={title} description={descricao} />
  </Card>
);

An unrelated note. This

() => { return whatever }

Is the same as:

() => whatever

So you could:

const returnCurses = cursos.map((curse, i) => (
  <div key={i}>
    <Card text={curse} />
  </div>
));

Note that index (i) is not a good key and anything but a loose linter will complain about this. If items in your array are added or removed, indices change, so the same key may refer to different items - not good.

Lastly, take cursos out the ListCurses. It's a const and doesn't change, yet you reallocate it on every render.

Upvotes: 1

Related Questions