我正在使用Redux和MUI为React中的预订网站创建一个购物车页面,并且我有一个用户可以从购物车中删除项目的表。我想为tableRow删除添加一个平滑的动画,但useRef钩子只对第一个选定的tableRow起作用。我如何动态选择正确的tableRow?这里是购物车页面的完整.tsx文件
import { Typography, TableContainer, Table, TableBody, TableHead, TableRow, TableCell, Paper, Stack, Grid, Button, IconButton } from "@mui/material";
import ShoppingCartCheckoutIcon from '@mui/icons-material/ShoppingCartCheckout';
import RemoveShoppingCartIcon from '@mui/icons-material/RemoveShoppingCart';
import { createTheme, ThemeProvider } from "@mui/material/styles";
import { NavBar } from "../components/navbar";
import { useSelector, useDispatch } from "react-redux";
import type { RootState } from "../redux/store";
import { clearCart, removeFromCart } from "../redux/slices/cartSlice";
import { useRef } from "react";
const customTheme = createTheme({
typography: {
fontFamily: [
'Satisfy',
'cursive'
].join(','),
}
})
export const CartPage = () => {
const tableRowRef = useRef<HTMLTableRowElement>(null);
const dispatch = useDispatch();
const cartItems = useSelector((state: RootState) => state.cart.cart);
const handleDeleteItem = (id: number) => {
const tableRow = tableRowRef.current;
if (tableRow) {
tableRow.style.animation = 'removeTableRow 1s';
setTimeout(() => {
tableRow.style.animation = '';
dispatch(removeFromCart(id));
}, 1000);
}
}
return (
<div>
<NavBar/>
<Stack direction='row' sx={{flexWrap: 'wrap'}} className='cartPage'>
<TableContainer className="scrollableTable" component={Paper} sx={{ width:'50vw', height: '92vh'}}>
<Table stickyHeader>
<TableHead>
<TableRow>
<TableCell sx={{ fontSize: '25px' }}><b>Where?</b></TableCell>
<TableCell sx={{ fontSize: '25px' }}><b>When?</b></TableCell>
<TableCell sx={{ fontSize: '25px' }}><b>Room</b></TableCell>
<TableCell sx={{ fontSize: '25px' }}><b>Price</b></TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{cartItems.map((item) => (
<TableRow key={item.id} ref={tableRowRef}>
<TableCell sx={{ fontSize: '20px' }}>{item.name}</TableCell>
<TableCell sx={{ fontSize: '20px' }}>{item.dates}</TableCell>
<TableCell sx={{ fontSize: '20px' }}><i>{item.room}</i></TableCell>
<TableCell sx={{ fontSize: '20px' }}>${item.price}</TableCell>
<TableCell>
<IconButton
color='error'
onClick={() => {handleDeleteItem(item.id)}}
>
<ShoppingCartCheckoutIcon fontSize="large" />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<Grid container justifyContent='center' sx={{width: '40vw'}}>
<Stack direction='column' justifyContent='space-evenly'>
<ThemeProvider theme={customTheme}>
<Typography variant="h1" className="cartPageCheckoutTypography" sx={{ color: '#74BF8B', textAlign: 'center'}}>
Satisfied?
</Typography>
</ThemeProvider>
<Stack direction='row' spacing={1.5}>
<Button
variant="contained"
color='success'
size="large"
sx={{ backgroundColor: '#5DBF9A', color: 'white', fontSize: '20px', width: '13vw' }}>
Confirm purchase
</Button>
<Button
variant="contained"
color='success'
size="large"
sx={{ backgroundColor: '#91BE77', color: 'white', fontSize: '20px', width: '13vw' }}
href='/book'>
Continue booking
</Button>
<Button
variant="contained"
color='success'
size="large"
sx={{ backgroundColor: '#B9BD5C', color: 'white', fontSize: '20px', width: '13vw' }}
onClick={()=>{dispatch(clearCart())}}
endIcon={<RemoveShoppingCartIcon />}
>
Clear cart
</Button>
</Stack>
</Stack>
</Grid>
</Stack>
</div>
);
};
我试过
const handleDeleteItem = (id: number) => {
const tableRow = tableRowRef.current;
if (tableRow) {
tableRow.style.animation = 'removeTableRow 1s';
setTimeout(() => {
tableRow.style.animation = '';
dispatch(removeFromCart(id));
}, 1000);
}
}
但它只对第一行有效。
有人能帮帮我吗?
1条答案
按热度按时间zpf6vheq1#
更新你的ref以使用数组而不是null:
在
cartItems.map()
方法中添加第二个参数,即index:然后更新标记:
同时更新handleDeleteItem方法: