Isidore Ducasse
Isidore Ducasse

Reputation: 501

TypeError: cards.map is not a function

I'm trying to learn react with hooks and at this point I am totally blind to what the issue is. The list renders correctly, but when I press the button I get a 'TypeError: cards.map is not a function' in my renderCardList(). Any help is mightily appreciated.

It works when i use the state in a class

import React, { useState } from 'react';
import RentalCard from './RentalCard';

const RentalCardList = () => {
    const [cards, setCards] = useState([
        { name: 'Anne`s', price: 234 },
        { name: 'John`s', price: 83 },
        { name: 'Mary`s', price: 733 }
    ]);

    const renderCardList = () => {
        return cards.map(c => (
            <RentalCard key={Math.random()} name={c.name} price={c.price} />
        ));
    };

    const add = obj => {
        setCards(cards.push(obj));
        console.log(cards);
    };

    return (
        <div className="container">
            <section id="rentalListing">
                <h1 className="page-title">Our hot listings</h1>
                <div className="row">{renderCardList()}</div>
            </section>
            <br />
            <button
                className="btn btn-primary"
                onClick={() => add({ name: 'jon', price: 27 })}
            >
                View others
            </button>
        </div>
    );
};

export default RentalCardList;

Upvotes: 0

Views: 1037

Answers (2)

goto
goto

Reputation: 4425

Your issue is with the way you're calling the setCards function to update cards state:

const RentalCardList = () => {
  // ...

  const add = obj = {
    setCards(cards.push(obj))
  }
}

This is wrong, as per the MDN documentation:

The push() method adds one or more elements to the end of an array and returns the new length of the array.

So when you're calling cards.push(obj) and setting the cards state with the return value from the cards.push() call, you're essentially just setting it to some integer, and your cards state is no longer an array.

Try this, instead:

const RentalCardList = () => {
  const add = obj = {
    setCards([
      ...cards,
      obj
    ])
  }
}

This way, you're creating a new array, copying items from the "old" array, and adding a new value(s) to the new array.

This method is called spread syntax and if you'd like to learn more, MDN has a good explanation:

Upvotes: 5

Merci Dieu KIMPOLO
Merci Dieu KIMPOLO

Reputation: 443

This can help

const add = obj => {
        setCards([...cards, obj]);
        console.log(cards);
    };

Upvotes: 0

Related Questions