简体   繁体   中英

Mapping over an array of objects to generate React components based on the key value pairs

EDIT: None of the solutions below worked for me as they were so after fiddling with ido ben ami's one I got this to work:

{
    array.map(project =>
        <Box>
            <Typography variant="subtitle1" sx={{fontWeight: 'bold', ml: 2}}
                        value={Object.keys(project)[0]}>{Object.keys(project)[0]}</Typography>
            {
                Object.entries(project)[0][1].map(ticket =>
                    <MenuItem sx={{ml: 3}} value={ticket}>{ticket}</MenuItem>)
            }
        </Box>
    )
}

I had originally used fragments instead of Box but Material UI doesn't like that for Select. If I left out one of these two it didn't work because the 2 components being generated are not the same.

The data from my backend is as such (number of projects/tickets varies obviously):

[
    {
        "Project 1": [
            "Ticket 1",
            "Ticket 2",
            "Ticket 3",
        ]
    },
    {
        "Project 2": [
            "Ticket 4"
            "Ticket 5"
            "Ticket 6"
        ]
    }
]

I need to map over it to generate items for my Select component. This is the outcome I'm after but I can't figure out how to do it with Object.entries or Object.keys/Object.values:

<Typography variant="subtitle1" sx={{fontWeight: 'bold', ml: 2}} value="Project 1">Project 1</Typography>
<MenuItem sx={{ml: 3}} value="Ticket 1">Ticket 1</MenuItem>
<MenuItem sx={{ml: 3}} value="Ticket 2">Ticket 2</MenuItem>
<MenuItem sx={{ml: 3}} value="Ticket 3">Ticket 3</MenuItem>

<Typography variant="subtitle1" sx={{fontWeight: 'bold', ml: 2}} value="Project 2">Project 2</Typography>
<MenuItem sx={{ml: 3}} value="Ticket 4">Ticket 4</MenuItem>
<MenuItem sx={{ml: 3}} value="Ticket 5">Ticket 5</MenuItem>
<MenuItem sx={{ml: 3}} value="Ticket 6">Ticket 6</MenuItem>

try this

<Box>
        {array.map((project, projectIndex) => (
            <Box key={projectIndex}>
                {console.log(Object.entries(project))}
                <Typography
                    variant="subtitle1"
                    sx={{ fontWeight: 'bold', ml: 2 }}
                    value={Object.entries(project)[0][0]}>
                    {Object.entries(project)[0][0]}
                </Typography>
                {Object.entries(project)[0][1].map((ticket, ticketIndex) => (<MenuItem key={ticketIndex} sx={{ ml: 3 }} value={ticket}>{ticket}</MenuItem>))}
            </Box> 
        ))}
    </Box>

but if you have access to make changes in the backend I will recommend to save the data like this:

[
{
 "projectName": "Project 1"
    "tickets": [
        "Ticket 1",
        "Ticket 2",
        "Ticket 3",
    ]
},
{
  "projectName": "Project 2"
    "tickets": [
        "Ticket 4"
        "Ticket 5"
        "Ticket 6"
    ]
}

]

You have an array of objects. In this objects you have only one properties. That properties is another array of string.

I do not know what is component Typography exatly doing and will be my solution good for your code and optimization but. you can try somthing like this:

Before rendering component (not JSX)

let backEndValue = [
  {
    "Project 1": [
      "Ticket 1",
      "Ticket 2",
      "Ticket 3",
    ]
  },
  {
    "Project 2": [
      "Ticket 4",
      "Ticket 5",
      "Ticket 6",
    ]
  }
]
const [title,setTitle] = useState('');
const [subTitle,setSubTitle] = useState('');

setProjects = [];

Object.keys(backEndValue).map((prop) => {
  return setProjects.push(backEndValue[prop]);
})
setProjects.map((prop)=>{
  const temp = Object.keys(prop);
  const tempT = prop[temp];

  setTitle(temp);
  setSubTitle(tempT);
})

In rendering (JSX)

{
title.map((prop,index)=>{
return <Typography key={index} variant="subtitle1" sx={{fontWeight: 'bold', ml: 2}} value={prop}>{prop}</Typography>
})
}
{
subTitle.map((prop,index)=>{
return <MenuItem key={index} sx={{ml: 3}} value={prop}>{prop}</MenuItem>
})
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM