大家好,我是DX3906。
最近遇到React高阶组件中Refs 不会被传递的问题。
在这里总结一下解决方案和解决思路:主要是通过从内向外和从外向内2种思路来分析解决的。
目录
前言
虽然高阶组件的约定是将所有 props 传递给被包装组件,但这对于 refs 并不适用。那是因为 ref
实际上并不是一个 prop - 就像 key
一样,它是由 React 专门处理的。如果将 ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。
在React中,Ref是一个React对象,它用于访问DOM节点或组件实例。当你使用高阶组件封装组件时,被封装的组件的Ref可能不会被传递到高阶组件的外部。这是因为高阶组件创建了一个包装组件,它接收原始组件作为prop,并且通常会创建一个新的ref来引用它。
解决方案一:React.forwardRef
解决这个问题的方法之一是使用React的React.forwardRef
函数。forwardRef
允许你将一个ref传递给子组件,这样即使组件被高阶组件封装,ref也能正确地传递到最底层的组件。
下面是一个使用React.forwardRef
的示例:
import React, { forwardRef } from 'react';
const EnhancedComponent = React.forwardRef((props, ref) => {
// 将ref传递给被封装的组件
return <WrappedComponent {...props} forwardedRef={ref} />;
});
const WrappedComponent = forwardRef((props, forwardedRef) => {
// 使用forwardedRef来访问DOM或组件实例
return <div ref={forwardedRef}>...</div>;
});
// 使用时,ref将被传递到WrappedComponent的div元素
const ref = React.createRef();
<EnhancedComponent ref={ref} />;
在这个例子中,EnhancedComponent
是一个高阶组件,它使用forwardRef
来接收一个ref,并将其传递给WrappedComponent
。WrappedComponent
也使用forwardRef
来接收这个ref,并将其应用到内部的DOM元素上。
使用forwardRef
可以确保无论组件被多少层高阶组件封装,ref都能正确地传递到最底层的组件。这使得你可以在需要的时候访问DOM节点或组件实例,而不受高阶组件的影响。
解决方案二:使用props传递ref
第一步:我们把ref 添加到 HOC 的返回组件中,则 ref 引用指向容器组件,而不是被包装组件。
第二步:在HOC 把被组装的组件的ref赋值给高阶组件外层的一个instance对象。然后使用第一步中的ref调用instance对象。
具体案例如下:
function withSubscription(WrappedComponent, selectData) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
data: selectData(props) // 初始状态
};
this.instance;
}
componentDidMount() {
// 订阅数据源
const { subscribe } = this.props;
subscribe(data => this.setState({ data }));
}
componentWillUnmount() {
// 取消订阅
const { unsubscribe } = this.props;
unsubscribe();
}
render() {
// 将数据和原始props传递给WrappedComponent
return <WrappedComponent ref={(node)=>{this.instance = node}} {...this.props} />;
}
};
}
import React,{useEffect,useRef} from "react"
function WithShow(props) {
let cusRef = useRef(null);
useEffect(()=>{
cusRef.current.instance.被包装组件的方法()
})
// 使用高阶组件
const MyComponentWithData = withSubscription(MyComponent, props => {
// 根据props选择数据
return someDataSource.getData(props.id);
});
// 然后在你的应用中使用MyComponentWithData
return() {
// 获取Hoc外层组件的ref
return <MyComponentWithData ref={cusRef} {...this.props} />;
}
};
}
结语
🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~