React项目中addEventListener绑定的click事件页面加载时意外触发如何解决
问题原因
- 你当前的核心问题是对同一个DOM元素重复绑定了点击事件监听器没有清理:
addEventListener调用时不会覆盖之前绑定的回调,只会追加新的回调。你的#header-link是跨路由复用的DOM元素,每次切换页面调用getLink都会新增一个点击回调,最终点击一次会触发所有绑定过的回调函数,就会出现先跳/test1、再跳/test的现象。 - 你用匿名函数作为事件回调,也导致无法通过
removeEventListener正常移除旧的监听器,进一步加剧了重复触发的问题。
修复方案
快速适配现有代码的方案
直接用onclick覆盖式赋值代替addEventListener,onclick每次赋值都会清空之前的回调,只会保留最后一次的逻辑,改动最小:
function getLink(currentPage, history) { const headerLink = document.getElementById("header-link") if(currentPage.name === 'test1') { // 直接赋值onclick,覆盖之前的回调 headerLink.onclick = function(e){ e.preventDefault(); window.location.pathname = '/test' }; document.getElementById("header-copy").innerHTML = 'Back'; } if (currentPage.name === 'test2') { headerLink.onclick = function(){ history.push('/test1') }; document.getElementById("header-copy").innerHTML = 'Previous'; } }
更符合React规范的方案(推荐)
不要直接操作原生DOM绑定事件,直接在Header组件内部用React的内置事件绑定逻辑,自动处理绑定和清理,从根源避免重复触发问题:
// Header.js 改写后 function Header({ currentPage, history }) { // 统一处理点击逻辑 const handleLinkClick = () => { if (currentPage.name === 'test1') { window.location.pathname = '/test' } else if (currentPage.name === 'test2') { history.push('/test1') } } // 动态生成文案 const linkText = currentPage.name === 'test1' ? 'Back' : 'Previous' return ( <div id="header-link" onClick={handleLinkClick}> <strong id="header-copy">{linkText}</strong> </div> ) }
使用时直接把currentPage和history作为props传给Header组件即可,无需再调用getLink操作DOM。
内容的提问来源于stack exchange,提问作者foshesco
相关产品推荐
相关产品推荐

