createReactClass与React类中this值差异及获取当前节点方案咨询
解决方案:在React类组件中正确获取DOM节点
首先得澄清一个点:标准React类组件里的this并非一直是undefined——大多是因为事件处理函数没正确绑定this,或是在非类方法的上下文(比如普通函数回调)里才会出现this丢失的情况。不过不管怎样,ReactDOM.findDOMNode已经是被官方标记为废弃的API了,现在更推荐用Refs来直接获取DOM节点,这也是更可靠、符合React设计理念的方式。
下面给你两种常用的实现方案:
1. 类属性+createRef(最简便)
箭头函数会自动绑定当前类实例的this,搭配createRef可以轻松创建DOM引用:
import React, { Component, createRef } from 'react'; class MyComponent extends Component { // 初始化一个ref实例 myElementRef = createRef(); componentDidMount() { // 组件挂载完成后,通过current就能拿到DOM节点 const domNode = this.myElementRef.current; if (domNode) { // 这里可以自由操作DOM,比如获取尺寸、添加监听等 console.log('获取到的DOM节点:', domNode); } } // 箭头函数自动绑定this,不用额外处理 handleClick = () => { const domNode = this.myElementRef.current; // 事件里也能正常访问ref console.log('点击事件中获取的节点:', domNode); } render() { // 将ref绑定到目标DOM元素上 return <div ref={this.myElementRef} onClick={this.handleClick}>点击测试</div>; } }
2. 回调Ref(灵活度更高)
如果需要在DOM节点挂载/卸载时执行额外逻辑,或者要动态绑定ref,可以用回调式的ref:
import React, { Component } from 'react'; class MyComponent extends Component { constructor(props) { super(props); this.myElementRef = null; // 手动绑定事件处理函数的this this.handleClick = this.handleClick.bind(this); } // 回调函数接收DOM节点作为参数 setMyElementRef = (node) => { this.myElementRef = node; if (node) { // 节点挂载时执行的逻辑 console.log('节点已挂载:', node); } else { // 节点卸载时执行的逻辑 console.log('节点已卸载'); } } componentDidMount() { if (this.myElementRef) { console.log('挂载后获取的节点:', this.myElementRef); } } handleClick() { // 这里的this已经通过bind绑定到类实例 console.log('点击事件中的节点:', this.myElementRef); } render() { return <div ref={this.setMyElementRef} onClick={this.handleClick}>点击测试</div>; } }
额外提醒:为什么弃用ReactDOM.findDOMNode?
React官方从16.3版本开始标记
ReactDOM.findDOMNode为废弃API,因为它会破坏组件封装性,当组件DOM结构变化时,容易出现不可预期的结果。而Refs是直接指向目标节点,逻辑更清晰可控。
另外如果你的类组件里确实出现this为undefined的情况,大概率是事件处理函数没绑定this——除了上面的箭头函数、bind绑定方式,还可以在render里直接写箭头函数(不过不推荐,会导致每次render创建新函数,影响性能):
render() { return <div onClick={() => this.handleClick()}>点击测试</div>; }
内容的提问来源于stack exchange,提问作者Mauricio Maroto
相关产品推荐
相关产品推荐

