redux 如何在表中使用Dinamically?

z2acfund  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(103)

我正在使用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);
        }
    }

但它只对第一行有效。
有人能帮帮我吗?

zpf6vheq

zpf6vheq1#

更新你的ref以使用数组而不是null:

const tableRowRef = useRef<HTMLTableRowElement[]>([]); // I'm not sure about the type in typescript for this

cartItems.map()方法中添加第二个参数,即index:

cartItems.map((item, idx)

然后更新标记:

<TableRow key={item.id} ref={(el) => (tableRowRef .current[idx] = el)}>

同时更新handleDeleteItem方法:

const handleDeleteItem = (id: number, idx: number) => {
const tableRow = tableRowRef.current[idx];
  if (tableRow) {
    tableRow.style.animation = "removeTableRow 1s";
    setTimeout(() => {
      tableRow.style.animation = "";
      dispatch(removeFromCart(id));
    }, 1000);
  }
};

相关问题