试图在已经映射的数据中映射数据
trying to map data inside of already mapped data
数据集 1 是一个数组,其中包含另一个数组数据集 2。数据集 1 当前映射到显示单个列 table,其中包含 data1.name。 data1.name是一个按钮,可以点击显示相关的data2.data。我目前面临的问题是,与其各自父项无关的数据集显示在所有父数据位置。例如,单击 data1[a] 将显示 data1[b] 中的所有 data2.data,依此类推。当我输入新数据 1 时,嵌套了新数据 2。之前在所有 data1 集中呈现的数据被这个新数据替换。
我附上了我的代码,希望有人能够阐明一些问题。请注意,我使用的是 MUI 库,因此代码有点笨重。有一个 table,它映射到 data1 上以显示每个 data1.name,然后在向用户呈现 data1.data2.data.[= 的模态显示后相对立即映射 data.2。 11=]
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
[`&.${tableCellClasses.body}`]: {
fontSize: 14,
},
}));
const StyledTableRow = styled(TableRow)(({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover,
},
// hide last border
'&:last-child td, &:last-child th': {
border: 0,
},
}));
const Reports = () => {
//GRAB THE USER PROFILE
const [users, setUsers] = useState({ months: [] })
useEffect(() => {
axios.get('/api/users/profile', {
headers: {
'Authorization': `Bearer ${localStorage.getItem('user')}`
}
}
)
.then(res => {
console.log(res.data)
setUsers({...users, months: res.data.months })
console.log(users.months)
})
}, [])
// defining modal styles
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 1000,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
// defining modal state
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
return (
<>
<NavBar></NavBar>
<br></br> <br></br>
<h1 style={{ color: "white", textAlign: "center", fontSize: "50px" }}>Budget Summaries</h1>
<br></br> <br></br>
<Container>
<Grid container spacing={2}>
<Grid item xs={0} md={1}>
</Grid>
<Grid item xs={12} md={10}>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 700 }} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell style={{ fontSize: "25px" }}>Month</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{users.months.map(month => (
<StyledTableRow key={month._id}>
<StyledTableCell component="th" scope="row">
<Button onClick={handleOpen}>{month.name}</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<Typography id="modal-modal-title" variant="h6" component="h2">
<Container>
< Grid container spacing={2} >
<Grid item xs={0} md={1}>
</Grid>
<Grid item xs={12} md={10}>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 700 }} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell style={{ fontSize: "25px" }}>Categories</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right">Spent</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right">Goals</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right">Results</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right"></StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{month.categories.map(category => (
<StyledTableRow key={category.name}>
<StyledTableCell component="th" scope="row">
{category.name}
</StyledTableCell>
<StyledTableCell align="right">{category.actualValue}</StyledTableCell>
<StyledTableCell align="right">{category.goalValue}</StyledTableCell>
<StyledTableCell align="right">{category.result}</StyledTableCell>
<StyledTableCell align="right"></StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
<Grid item xs={0} md={1}>
</Grid>
</Grid >
</Container >
</Typography>
</Box>
</Modal>
</StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
<Grid item xs={0} md={1}>
</Grid>
</Grid>
</Container>
<br></br><br></br>
<hr style={{ color: "white" }}></hr>
<Footer></Footer>
</>
)
}
export default Reports
请尝试按照建议替换以下代码片段:
1.
// defining modal state
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
与
// defining modal state
const [open, setOpen] = React.useState({});
const handleOpen = monthId => setOpen(prev => ({...prev, [monthId]: true}));
const handleClose = monthId => setOpen(prev => ({...prev, [monthId]: false}));
<Button onClick={handleOpen}>{month.name}</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
与
<Button onClick={() => handleOpen(month._id)}>{month.name}</Button>
<Modal
open={open[month._id]}
onClose={() => handleClose(month._id)}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
说明
- 当前代码只有一个名为
open
的 state-variable,只要用户单击 month.name
按钮,它就会设置为 true
。
- 当它设置为真时,所有具有
<Modal open={open}...
的模态将是rendered/displayed
- 上面建议的更改将使
open
成为 { monthId1: false, monthId2: true, ......}
形式的对象
- 对
handleOpen
和 handleClose
的更改将确保仅更新特定月份的 open/close 标志
- 将
<Modal open={open} ....
替换为 <Modal open={open[month._id]} ....
,确保每个模态都使用特定于 month._id
的 true/false。
- 注意:如果
month._id
可能重复,则使用不同的唯一属性。如果不存在这样的属性,则将 {users.months.map(month => (
替换为 {users.months.map((month, monthIndex) => (
并使用 monthIndex
.
观察/注意
我们可以通过使用简单的 flip
方法来避免 handleOpen
、handleClose
方法,如下所示:
const flip = monthId => setOpen(prev => ({...prev, [monthId]: !prev[monthId]}));
所以,onClick
和onClose
都会变成这样:
{() => flip(month._id)}
数据集 1 是一个数组,其中包含另一个数组数据集 2。数据集 1 当前映射到显示单个列 table,其中包含 data1.name。 data1.name是一个按钮,可以点击显示相关的data2.data。我目前面临的问题是,与其各自父项无关的数据集显示在所有父数据位置。例如,单击 data1[a] 将显示 data1[b] 中的所有 data2.data,依此类推。当我输入新数据 1 时,嵌套了新数据 2。之前在所有 data1 集中呈现的数据被这个新数据替换。
我附上了我的代码,希望有人能够阐明一些问题。请注意,我使用的是 MUI 库,因此代码有点笨重。有一个 table,它映射到 data1 上以显示每个 data1.name,然后在向用户呈现 data1.data2.data.[= 的模态显示后相对立即映射 data.2。 11=]
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
[`&.${tableCellClasses.body}`]: {
fontSize: 14,
},
}));
const StyledTableRow = styled(TableRow)(({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover,
},
// hide last border
'&:last-child td, &:last-child th': {
border: 0,
},
}));
const Reports = () => {
//GRAB THE USER PROFILE
const [users, setUsers] = useState({ months: [] })
useEffect(() => {
axios.get('/api/users/profile', {
headers: {
'Authorization': `Bearer ${localStorage.getItem('user')}`
}
}
)
.then(res => {
console.log(res.data)
setUsers({...users, months: res.data.months })
console.log(users.months)
})
}, [])
// defining modal styles
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 1000,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
// defining modal state
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
return (
<>
<NavBar></NavBar>
<br></br> <br></br>
<h1 style={{ color: "white", textAlign: "center", fontSize: "50px" }}>Budget Summaries</h1>
<br></br> <br></br>
<Container>
<Grid container spacing={2}>
<Grid item xs={0} md={1}>
</Grid>
<Grid item xs={12} md={10}>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 700 }} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell style={{ fontSize: "25px" }}>Month</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{users.months.map(month => (
<StyledTableRow key={month._id}>
<StyledTableCell component="th" scope="row">
<Button onClick={handleOpen}>{month.name}</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<Typography id="modal-modal-title" variant="h6" component="h2">
<Container>
< Grid container spacing={2} >
<Grid item xs={0} md={1}>
</Grid>
<Grid item xs={12} md={10}>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 700 }} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell style={{ fontSize: "25px" }}>Categories</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right">Spent</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right">Goals</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right">Results</StyledTableCell>
<StyledTableCell style={{ fontSize: "25px" }} align="right"></StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{month.categories.map(category => (
<StyledTableRow key={category.name}>
<StyledTableCell component="th" scope="row">
{category.name}
</StyledTableCell>
<StyledTableCell align="right">{category.actualValue}</StyledTableCell>
<StyledTableCell align="right">{category.goalValue}</StyledTableCell>
<StyledTableCell align="right">{category.result}</StyledTableCell>
<StyledTableCell align="right"></StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
<Grid item xs={0} md={1}>
</Grid>
</Grid >
</Container >
</Typography>
</Box>
</Modal>
</StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
<Grid item xs={0} md={1}>
</Grid>
</Grid>
</Container>
<br></br><br></br>
<hr style={{ color: "white" }}></hr>
<Footer></Footer>
</>
)
}
export default Reports
请尝试按照建议替换以下代码片段:
1.
// defining modal state
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
与
// defining modal state
const [open, setOpen] = React.useState({});
const handleOpen = monthId => setOpen(prev => ({...prev, [monthId]: true}));
const handleClose = monthId => setOpen(prev => ({...prev, [monthId]: false}));
<Button onClick={handleOpen}>{month.name}</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
与
<Button onClick={() => handleOpen(month._id)}>{month.name}</Button>
<Modal
open={open[month._id]}
onClose={() => handleClose(month._id)}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
说明
- 当前代码只有一个名为
open
的 state-variable,只要用户单击month.name
按钮,它就会设置为true
。 - 当它设置为真时,所有具有
<Modal open={open}...
的模态将是rendered/displayed - 上面建议的更改将使
open
成为{ monthId1: false, monthId2: true, ......}
形式的对象
- 对
handleOpen
和handleClose
的更改将确保仅更新特定月份的 open/close 标志 - 将
<Modal open={open} ....
替换为<Modal open={open[month._id]} ....
,确保每个模态都使用特定于month._id
的 true/false。 - 注意:如果
month._id
可能重复,则使用不同的唯一属性。如果不存在这样的属性,则将{users.months.map(month => (
替换为{users.months.map((month, monthIndex) => (
并使用monthIndex
.
观察/注意
我们可以通过使用简单的 flip
方法来避免 handleOpen
、handleClose
方法,如下所示:
const flip = monthId => setOpen(prev => ({...prev, [monthId]: !prev[monthId]}));
所以,onClick
和onClose
都会变成这样:
{() => flip(month._id)}