React圆形点击撤销操作失效求助:扩展运算符是否适用?
React圆形点击撤销功能失效排查与解决
问题描述
实战学习React时碰到撤销功能失效的问题:点击Undo按钮毫无反应,控制台也没有报错,但点击画布添加圆形的事件能正常打印日志。不确定是否该使用扩展运算符,同时想了解相关性能优化方案。
问题根源
代码里的button元素嵌套在绑定了handlePlaceCircle点击事件的circleApp容器内。由于React的事件冒泡机制,点击Undo按钮时,事件会向上冒泡到父容器,触发handlePlaceCircle添加新的点,直接抵消了handleUndo的删除操作,导致撤销功能看起来失效。
修复方案
在按钮的点击事件处理函数中添加e.stopPropagation()阻止事件冒泡即可解决:
function handleUndo(e: React.MouseEvent<HTMLButtonElement>) { e.stopPropagation(); const newPoints = [...points]; newPoints.pop(); setPoints(newPoints); }
扩展运算符的合理性
你当前用扩展运算符[...points]复制数组是完全合理的,这是React状态更新中避免直接修改原状态的标准做法,保障了状态的不可变性,没有问题。
性能优化建议
- 采用函数式状态更新:当新状态依赖旧状态时,推荐使用
setPoints的函数式更新形式,避免闭包导致的状态不一致问题,尤其适用于频繁更新的场景:
// 添加圆形的函数优化 function handlePlaceCircle(e: React.MouseEvent<HTMLDivElement>) { const { clientX, clientY } = e; setPoints(prevPoints => [...prevPoints, { x: clientX, y: clientY }]); } // 撤销函数优化 function handleUndo(e: React.MouseEvent<HTMLButtonElement>) { e.stopPropagation(); setPoints(prevPoints => prevPoints.slice(0, -1)); }
- 给列表元素添加唯一key:
points.map渲染圆形时,必须给每个div添加唯一key值,避免React渲染时出现错误的组件复用:
{points.map((point, index) => ( <div key={index} // 若后续点有唯一标识(如UUID),建议替换为该标识 className="point" style={{ left: point.x - 5 + 'px', top: point.y - 5 + 'px', }} > o </div> ))}
内容的提问来源于stack exchange,提问作者zi zi
相关产品推荐
相关产品推荐

