React onClick与原生addEventListener点击事件逻辑及事件目标校验问题
React onClick事件机制相关问题解答
1. React onClick的自动分发与校验必要性
React内部基于合成事件系统实现了完整的事件监听、分发逻辑。你给每个按钮独立绑定的onClick回调,React会自动维护回调与对应DOM元素的映射关系,事件触发时会精准分发到对应元素绑定的处理函数,完全不需要你额外校验事件目标是否匹配。
你无需像原生全局事件委托那样判断event.target属性,即使点击的是按钮内部的子元素(比如你代码里的<i>标签),事件冒泡到绑定onClick的按钮节点时,也会正确触发对应的回调。
2. 原生addEventListener与React onClick的触发关系
两者是独立运行的两套事件机制,只要你没有在任意阶段的事件回调中调用event.stopPropagation()阻止事件冒泡,React的onClick就会正常触发,不会被原生绑定的监听影响。
需要注意事件触发顺序:你绑定在window上的原生click事件(addEventListener第三个参数默认false,即冒泡阶段触发),触发时机晚于React的合成onClick事件。标准的触发流为:
- 原生捕获阶段:从window向下逐层传递到目标按钮
- 原生目标阶段:触发按钮本身绑定的原生事件
- 原生冒泡阶段:从按钮向上逐层冒泡,到达React应用根容器时触发React合成
onClick事件,继续冒泡到window时触发你绑定的ontoggleExpandUpper、ontoggleExpandLower回调
3. React对两类事件的区分逻辑
React不需要区分两类事件,因为合成事件系统和浏览器原生事件系统是完全独立的两套实现:
- 原生
addEventListener绑定的回调由浏览器内核直接管理、触发 - React的
onClick回调全部由React内部的合成事件系统维护,它仅在自己的根委托节点上监听原生事件,收到事件后仅触发自己内部映射表中绑定的对应回调,不会干预原生绑定的回调,也不需要做额外区分。
代码优化建议
你当前给uexp、lexp按钮绑定全局window监听再加类名判断的写法可以直接简化,给对应按钮绑定React onClick即可,无需额外做目标校验,代码更简洁易维护:
<button id="uexp" className="uexp" onClick={this.ontoggleExpandUpper.bind(this)}> <i id="iuexp" className="uexp"></i> </button> <button id="lexp" className="lexp" onClick={this.ontoggleExpandLower.bind(this)}> <i id="ilexp" className="lexp"></i> </button>
另外注意你现有代码里第一个按钮的onClick后缺少等号,正确写法为onClick={() => this.toggleSidebar()}。
内容的提问来源于stack exchange,提问作者smartblonde
相关产品推荐
相关产品推荐

