0

I'm using material-ui library to create card like items. I have the list of items stored in a js file like this:-

var Data = [
  {
    name: "Tandoori Pizza",
    image: "Images/pizza.png",
    price: "Rs.200",
    sizes: { Small: 100, Medium: 200, Large: 300 },
  },
  {
    name: "Veggie Supreme",
    image: "Images/pizza.png",
    price: "Rs.250",
    sizes: { Small: 100, Medium: 200, Large: 300 },
  }
]

And this is the function in which I wish to use Data.map(item => //something)

import Data from "./data";
    const useStyles = makeStyles({
      root: {
        maxWidth: 345,
      },
      media: {
        height: 140,
      },
    });
    function MediaCard() {
      const classes = useStyles();
      return (
        <Card className={classes.root}>
          <CardActionArea>
            <CardMedia
              className={classes.media}
              image="/static/images/cards/contemplative-reptile.jpg"
              title="Contemplative Reptile"
            />
            <CardContent>
              <Typography gutterBottom variant="h5" component="h2">
                Lizard
              </Typography>
              <Typography variant="body2" color="textSecondary" component="p">
                Lizards are a widespread group of squamate reptiles, with over 6,000
                species, ranging across all continents except Antarctica
              </Typography>
            </CardContent>
          </CardActionArea>
          <CardActions>
            <Button size="small" color="primary">
              Add to Cart
            </Button>
          </CardActions>
        </Card>
      );
    }

Could someone tell me how do I write the syntax for Data.map() to render all the items present in data.js using MediaCard() ?

4
  • Do you want to use map() inside of your MediaCard component or use MediaCard inside of map() and pass the data to the component? if that makes sense Commented May 9, 2021 at 21:46
  • Anyway is fine. I'm not sure which one is more efficient though. Commented May 9, 2021 at 21:47
  • 2
    Probably less clutter in the app and make MediaCard reusable if you create a higher level component that maps the data to return individual <MediaCard {props}/> Commented May 9, 2021 at 21:58
  • @charlietfl I actually thought of making MediaCard as another file itself but wasn't sure how to do it. If possible, could you give me a snippet of it, pls? Commented May 9, 2021 at 22:00

3 Answers 3

1

You could try this, you have to loop at every item and render a component.

 const useStyles = makeStyles({
    root: {
        maxWidth: 345,
    },
    media: {
        height: 140,
    },
});
function MediaCard() {
    const Data = [
        {
            name: "Tandoori Pizza",
            image: "Images/pizza.png",
            price: "Rs.200",
            sizes: { Small: 100, Medium: 200, Large: 300 },
        },
        {
            name: "Veggie Supreme",
            image: "Images/pizza.png",
            price: "Rs.250",
            sizes: { Small: 100, Medium: 200, Large: 300 },
        },
    ];
    const classes = useStyles();
    return (
        <>
            {Data.map((item) => {
                return (
                    <Card className={classes.root}>
                        <CardActionArea>
                            <CardMedia
                                className={classes.media}
                                image={"/static/" + item.image} // put your images inside static folder.
                                title={item.name}
                            />
                            <CardContent>
                                <Typography
                                    gutterBottom
                                    variant="h5"
                                    component="h2"
                                >
                                    {item.name}
                                </Typography>
                                <Typography
                                    gutterBottom
                                    variant="h5"
                                    component="h2"
                                >
                                    Price: {item.price}
                                </Typography>
                            </CardContent>
                        </CardActionArea>
                        <CardActions>
                            <Button size="small" color="primary">
                                Add to Cart
                            </Button>
                        </CardActions>
                    </Card>
                );
            })}
        </>
    );
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for answering. How do I use item.name, item.image, item.price in the above code?
As I mentioned in the code, you could pass the image to CardMedia as a prop, the image must be an URL or path but you have to tweak it(the images must moved to static folder and use the path "/static/"+item.image). For the price you can display it inside Typography, I updated the snippet to include the price.
I'm getting this error: Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
I think the problem in the import data, try to use data directly in your component, I completed the snippet. You could check the code.
This mapping should be in a higher level component. <MediaCard/> should only be responsible for one item
|
1

I don't know what kind of information you want to put in your program, and where you would want to put it, as your two examples don't match up the best or at least don't make sense to me.

https://www.freecodecamp.org/learn/front-end-libraries/react/change-inline-css-conditionally-based-on-component-state

This lesson comes to mind though, and seems to do exactly what you're asking for. I just don't know how you want to implement it exactly, so I can't say how I'd write the map function.

Otherwise, I'd write something like...

const cardList = Data.map(x => {
   return (<li><CardMedia
              className={Data.name}
              image={Data.image}
              title={Data.name}
            /></li>);
});

And somewhere else in your program, you can just pop cardList inside another space, like so...

<ul>{cardList}<ul>

Unfortunately, without a better example I can't say what more I could do. As is, you don't have a render() function in there or any kind of state, which you could use to store your imported data.

Comments

1

You want to make MediaCard responsible for one item only. Create a higher level component that maps an array of <MediaCard/> items.

That higher level component can then also be used to do filtering of the data array to only render items that meet a specific criteria such as category or price or ??

Following is a simple list example using a <MenuList/> that maps a simplified version of your MediaCard

const App = () => {  
  return (
    <div>
      <h3>Menu</h3>      
      <MenuList/>;
    </div>
  );
}

const MenuList = () => {
  const [items, setItems] = React.useState(Data); 
  return ( 
    <div>  
      <div>Some filters here for various categories or price filter</div>  
      <ul>{items.map((item) => (<MediaCard item={item} />))}</ul>  
    </div> 
  );
};

const MediaCard = ({ item }) => {
  return (
    <li>
      <h4>{item.name}</h4>
      <div>Price: {item.price}</div>
    </li>
  );
};

// Render it
ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
<script>
var Data=[{name:"Tandoori Pizza",image:"Images/pizza.png",price:"Rs.200",sizes:{Small:100,Medium:200,Large:300}},{name:"Veggie Supreme",image:"Images/pizza.png",price:"Rs.250",sizes:{Small:100,Medium:200,Large:300}}];
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.