ReactDOM.findDOMNode()已废弃,求替代方案及代码修正指导
我来帮你理清这里的问题,以及给出正确的修改方案~
首先纠正你之前的理解误区:当你把ref绑定到类组件(比如你的someComponent1)上时,拿到的其实是该组件的实例对象,而不是直接的DOM元素。这就是为什么你直接传this.expand给Expand会失效——它需要的是DOM节点,而不是组件实例。
findDOMNode()的作用就是从组件实例中提取它的根DOM节点,但这个API因为会带来一些副作用(比如打破封装、影响React的更新逻辑)被废弃了,所以我们需要用更规范的ref转发方式来获取DOM节点。
下面分两种情况给出解决方案:
情况1:你可以修改someComponent1的代码
如果someComponent1是你自己维护的组件,我们可以给它加上ref转发,让外部能直接拿到它内部的根DOM元素:
如果someComponent1是函数组件
用React.forwardRef包裹它,把外部传入的ref绑定到内部的根DOM元素上:
import React, { forwardRef } from 'react'; const someComponent1 = forwardRef((props, ref) => { // 把ref绑定到组件的根DOM元素(比如这里的div) return ( <div ref={ref} className={props.className}> {/* 组件内部内容 */} </div> ); });
如果someComponent1是类组件
可以通过props传递ref(比如命名为innerRef),或者用forwardRef包裹类组件:
import React, { forwardRef, Component } from 'react'; class SomeComponent1 extends Component { render() { return ( <div ref={this.props.innerRef} className={this.props.className}> {/* 组件内部内容 */} </div> ); } } // 用forwardRef包裹,让外部可以直接传递ref const someComponent1 = forwardRef((props, ref) => { return <SomeComponent1 {...props} innerRef={ref} />; });
完成someComponent1的改造后,就可以在classA里直接用ref获取DOM节点了:
import React, { Component, createRef } from 'react'; import someComponent1 from './someComponent1'; import Expand from './Expand'; class classA extends Component { constructor(props) { super(props); // 创建一个ref对象 this.expandRef = createRef(); } componentDidMount() { // 现在ref.current就是直接的DOM节点了 new Expand(this.expandRef.current); } render() { return ( <someComponent1 className={style.container} ref={this.expandRef} /> ); } }
情况2:你无法修改someComponent1(比如是第三方组件)
如果someComponent1是第三方库的组件,且没有提供ref转发的支持,那我们可以换个思路:在someComponent1外面包一层原生DOM元素(比如div),把ref绑定到这个外层元素上,然后传给Expand:
class classA extends Component { constructor(props) { super(props); this.expandRef = createRef(); } componentDidMount() { new Expand(this.expandRef.current); } render() { return ( <div ref={this.expandRef} className={style.container}> <someComponent1 /> </div> ); } }
注意:这种方式需要确保
Expand的逻辑可以适配外层DOM元素,如果它必须作用于someComponent1内部的特定节点,那可能需要查看该第三方组件的文档,看是否有其他API可以获取内部DOM节点,或者提供了初始化的回调。
内容的提问来源于stack exchange,提问作者Bishal Jain

