React MUI Chip组件onDelete触发时如何阻止NavLink跳转
问题根因
你调用stopPropagation不生效,不是事件对象上没有这个方法,是调用时机不对:MUI Chip内部会先处理删除按钮的点击事件,等回调触发的时候,事件已经冒泡到外层作为根元素的NavLink上,已经满足跳转触发条件了,这时候再阻止冒泡来不及。
可行解决方案
- 方案1:手动控制跳转逻辑(最稳妥,无兼容问题)
不要直接给Chip传component={NavLink},改用路由的跳转方法在Chip的点击事件里主动触发跳转,删除事件里正常阻止冒泡即可,两个事件完全互不干扰:
import { Chip } from '@mui/material'; import { useNavigate } from 'react-router-dom'; // 组件内部逻辑 const navigate = useNavigate(); const handleChipClick = () => { navigate(to); }; const handleDelete = (e) => { e.stopPropagation(); // 这里写你的删除业务逻辑 }; return ( <Chip label={name} sx={sx} clickable onClick={handleChipClick} onDelete={handleDelete} /> );
- 方案2:保留NavLink作为component的写法,在自定义删除图标上拦截事件
如果你不想改动现有跳转写法,可以通过deleteIcon属性传入自定义删除图标,在图标上提前拦截点击、鼠标按下事件,阻止事件冒泡到外层NavLink:
import { Chip } from '@mui/material'; import CancelIcon from '@mui/icons-material/Cancel'; const handleDelete = (e) => { // 这里写你的删除业务逻辑 }; const deleteEventInterceptor = (e) => { e.stopPropagation(); e.preventDefault(); }; return ( <Chip label={name} sx={sx} component={NavLink} to={to} clickable onDelete={handleDelete} deleteIcon={ <CancelIcon onMouseDown={deleteEventInterceptor} onClick={deleteEventInterceptor} /> } /> );
这里额外加onMouseDown拦截是为了阻止MUI组件内部在鼠标按下阶段触发的交互逻辑,避免遗漏事件冒泡路径。
优先选第一种方案,逻辑直白没有黑魔法,后续迭代不会因为MUI内部实现变动出问题。
内容的提问来源于stack exchange,提问作者Kostanos
相关产品推荐
相关产品推荐

