Reputation: 501
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
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
Reputation: 443
This can help
const add = obj => {
setCards([...cards, obj]);
console.log(cards);
};
Upvotes: 0