I'm trying to return a list of 'cards', each containing three components.
The parent, ItemCard, returns this:
<>
<article>
<ItemName data={items} />
<ItemMap data={items} />
<FavouriteButton data={items} />
</article>
</>
)
The child components each have a .map to render each item from the array:
const ItemName = (props) => {
return (
<>
{props.data.map((item) =>
<p key={item.title}>{item.title}</p>
)}
</>
)
}
I would like to surround the three components returned from ItemCard so that each instance is its own article. Currently I get one big article containing a list of ItemNames, then ItemMaps, then Buttons. I'd like 25 individual articles, each with ItemName, ItemMap and Button.
My only idea was to use a forEach to do this, but I can't get it working.
Any tips much appreciated!
CodePudding user response:
Hi Hanna and welcome to stack overflow. You almost got the right answer with the data.map function. You just need to put the article inside the return of the map iterator.
const App = (props) => {
return (
<>
{props.data.map((item) => (
<ItemCard item={item} />
))}
</>
);
};
const ItemCard = ({item}) => {
return (
<article>
<ItemName item={item} />
<ItemMap item={item} />
<FavouriteButton item={item} />
</article>
);
};
You'll need to change the implementation of ItemName, ItemMap and FavouriteButton to account for the change in props structure.
CodePudding user response:
Thanks so much for your help!
I've refactored with your suggestions in mind but can't get it working properly. I've now got the parent as ItemsListContainer, and this component fetches the data, stores it in state and returns the ItemCard(s).
const dataUrl = "https://s3-eu-west-1.amazonaws.com/olio-staging-images/developer/test-articles-v4.json"
const ItemsListContainer = () => {
const [items, setItems] = useState([])
const fetchItemData = async () => {
const response = await fetch(dataUrl)
const jsonData = await response.json()
setItems(jsonData)
console.log(items)
}
useEffect(() => {
fetchItemData()
}, [])
if(items.length > 0) {
return (
<>
{items.map((item) => (
<ItemCard item={item} />
))}
</>
)
} else {
return (
<div>Loading items...</div>
)
}
}
ItemCard returns the three components:
const ItemCard = ({item}) => {
return (
<>
<article>
<ItemName item={item} />
<ItemMap item={item} />
<FavouriteButton item={item} />
</article>
</>
)
}
ItemName returns each:
const ItemName = (props) => {
console.log(props.item.title)
return (
<>
{props.item.map((item) => (
<p key={item.title}>{item.title}</p>
))}
</>
)
}
The error I get in the console is 'Uncaught TypeError: props.item.map is not a function at ItemName (ItemName.js:6)'.
The console.log works and prints what I want displayed in the p tag.
