React中event.currentTarget为null时如何获取事件绑定的目标元素
问题现象原因说明
this = undefined的原因:你使用的是函数式组件(箭头函数定义的App属于函数组件),函数组件没有组件实例,本身就不存在this,这是React的正常特性,不属于错误。event.currentTarget = null的原因:React使用自研的合成事件体系,为了提升性能会对事件对象做池化复用,事件回调函数执行完成后,事件对象的所有属性都会被重置回收,如果你的代码在异步逻辑(比如setTimeout、接口请求回调、Promise回调等)中访问event.currentTarget,就会拿到null。
事件绑定元素获取方案
场景1:同步访问元素
你给出的示例代码本身同步打印event.currentTarget是完全正常的,可以直接拿到绑定事件的div元素,不需要额外处理:
const App = () => ( <div onMouseEnter={(event) => console.log(event.currentTarget)}> <span>HELLO</span> </div> );
场景2:异步访问元素
可任选以下一种方案实现:
- 方案1:提前保存currentTarget引用
在事件回调开头先把event.currentTarget赋值给局部变量,后续异步逻辑直接访问该变量即可:
const App = () => ( <div onMouseEnter={(event) => { const bindElement = event.currentTarget; setTimeout(() => { console.log(bindElement); // 正常拿到绑定的div元素 }, 100) }}> <span>HELLO</span> </div> );
- 方案2:调用
event.persist()
调用该方法会将当前合成事件从事件池中移除,不会被重置回收,后续异步访问也能拿到完整的事件属性:
const App = () => ( <div onMouseEnter={(event) => { event.persist(); setTimeout(() => { console.log(event.currentTarget); // 正常拿到绑定的div元素 }, 100) }}> <span>HELLO</span> </div> );
- 方案3:给元素绑定ref
通过useRef钩子给绑定事件的元素挂载ref,不管什么时候都可以通过ref.current拿到元素,不受事件池机制影响:
import { useRef } from 'react'; const App = () => { const divRef = useRef(null); return ( <div ref={divRef} onMouseEnter={() => { setTimeout(() => { console.log(divRef.current); // 正常拿到绑定的div元素 }, 100) }}> <span>HELLO</span> </div> ) };
类组件this指向修复
如果你使用类组件需要拿到组件实例的this,可以用类属性箭头函数的方式写事件处理,自动绑定this指向:
class App extends React.Component { handleMouseEnter = (e) => { console.log(this); // 指向App组件实例,不会是undefined console.log(e.currentTarget); // 同步访问直接拿到绑定的div } render() { return ( <div onMouseEnter={this.handleMouseEnter}> <span>HELLO</span> </div> ) } }
内容的提问来源于stack exchange,提问作者Obiwahn
相关产品推荐
相关产品推荐

