React实现可点击且不触发行mouseLeave事件的SVG功能问题
解决方案
核心问题出在实现思路不符合React声明式渲染的逻辑:手动操作DOM修改样式、调用ReactDOM.render动态挂载内容的写法,会导致事件绑定异常、组件上下文脱节,这是你遇到两个问题的根本原因。
修正方案
- 用React内置的
useState管理行的悬浮状态,替代所有手动DOM操作,所有样式、显示内容都通过状态驱动渲染 - 直接在JSX中声明SVG元素和点击事件,天然可以访问组件内部变量、props传递的外部函数
- React合成的
onMouseEnter/onMouseLeave事件本身不冒泡,只有真正进出行元素边界时才会触发,不需要给SVG设置pointer-events属性,也不会出现鼠标移到SVG上就触发行离开事件的问题
如果需要触发外部传入的函数,只需要在调用Library组件时传入对应props即可,例如<Library onSvgClick={你的外部函数} />,在SVG点击回调中直接调用props.onSvgClick就能执行外部逻辑。
修正后完整代码
JS代码
const { Container, Row, Col} = ReactBootstrap; const { useState } = React; function Library(props){ // 用state管理悬浮状态 const [isHover, setIsHover] = useState(false); // SVG点击函数,可直接调用props传入的外部方法 function handleSvgClick(e) { e.stopPropagation(); // 防止点击事件冒泡触发行的其他事件 console.log('clicked'); // 直接调用props传入的函数即可,例如:props.onSvgClick?.() } return( <Container> <Row style={{background: isHover ? 'blue' : 'red'}} onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)} > <Col> <div id="content"> {isHover ? ( <svg width="0.75rem" height="0.75rem" className="Layer_1" x="0px" y="0px" viewBox="0 0 472.615 472.615" fill="white"> <polygon onClick={handleSvgClick} points="50.273,0 50.273,472.615 422.342,236.308"/> </svg> ) : "hover over me and click the button!"} </div> </Col> </Row> </Container> ) } ReactDOM.render( <Library/>, document.getElementById('root') );
CSS代码
.row{ background:red; }
HTML代码(和原有一致无需修改)
<script src="https://unpkg.com/react/umd/react.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js" crossorigin></script> <div id="root"></div>
内容的提问来源于stack exchange,提问作者Clueless
相关产品推荐
相关产品推荐

