@andrey_chirkin

Почему некорректно работает onClick в цикле map?

Здравствуйте! Я с помощью map вывожу таблицу. На теге <tr/>у меня весит обработчик onClick, с помощью которого в стейт записывается нажатая строка.
При на нажатии на кнопку удалить у меня удаляется строка, находящаяся ниже, а не та, в которой находится кнопка удалить. Подскажите, пожалуйста, как это исправить.

Вывод строк:

const OutputOperations = observer(({item, index}) => {

    const {dataTable} = TechStore

    const handleClick = (index, item) => (
        () => {
            dataTable.forEach((operation) => {
                operation["clicked"] = false
            })
            item["clicked"] = true
            dataTable[index] = item
        }
    )

    return (
        <tr
            style={dataTable[index]["clicked"] ? {
                backgroundColor: "#E4F2FE"
            } : {}}
            onClick={handleClick(index, item)}
        >
            <OutputOperation
                item={item}
                index={index}
            />
            <td>
                <div className="groupButton">
                    <ButtonEditOperation index={index} item={item}/>
                    <ButtonAddContentOperation index={index}/>
                    <ButtonDeleteOperation index={index}/>
                </div>
            </td>
        </tr>
    )
})


Логика в компоненте ButtonDeleteOperation:
import React, {useState} from 'react'
import {Button, Fab, Menu} from "@mui/material"
import DeleteForeverIcon from '@mui/icons-material/DeleteForever'
import {observer} from "mobx-react"
import {toJS} from "mobx"
import CheckIcon from "@mui/icons-material/Check"
import CloseIcon from "@mui/icons-material/Close"
import TechStore from "../../../../../TechStore"

const ButtonDeleteOperation = observer(({index}) => {

    const {dataTable} = TechStore

    const handleClickDeleteItem = () => {
        dataTable.splice(index, 1)
        setAnchorEl(null)
    }

    const [anchorEl, setAnchorEl] = useState(null)
    const open = Boolean(anchorEl)

    const handleClick = (event) => {
        setAnchorEl(event.currentTarget)
    }

    const handleClose = () => {
        setAnchorEl(null)
    }

    return (
        <>
            <Button
                onClick={handleClick}
                sx={{
                    color: 'red'
                }}
            >
                <DeleteForeverIcon fontSize="small"/>
            </Button>
            <Menu
                anchorEl={anchorEl}
                open={open}
                onClose={handleClose}
                sx={{
                    '& .MuiMenu-paper': {
                        padding: '10px'
                    }
                }}
            >
                <p style={{fontSize: '14px', fontWeight: 'bold'}}> Подтвердить </p>
                <Fab
                    color="primary"
                    size="small"
                    onClick={handleClickDeleteItem}
                >
                    <CheckIcon/>
                </Fab>
                <Fab
                    size="small"
                    sx={{
                        backgroundColor: 'red',
                        color: '#fff',
                        marginLeft: '7px',
                        ':hover': {
                            backgroundColor: '#b22a00'
                        }
                    }}
                    onClick={handleClose}
                >
                    <CloseIcon/>
                </Fab>
            </Menu>
        </>
    )
})

export default ButtonDeleteOperation


Исходная таблица:
62289e9199ea6408519163.png
После нажатия на корзину (красную кнопку справа):
62289ed3eafc8625001750.png
  • Вопрос задан
  • 150 просмотров
Решения вопроса 1
Alexandroppolus
@Alexandroppolus
кодир
У тебя после обработчика кнопки удаления срабатывает ещё и обработчик клика по строке - всплытие никто не отменял. Вот так и получается, что сначала удаляешь элемент массива (остальные сьезжают на один влево), а потом поверх первого сьехавшего записываешь старый удаленный итем
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы