这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
按惯例看下react官网对ref的介绍:Ref 转发是一项将 ref 自动地通过组件传递到其一子组件的技巧。对于大多数应用中的组件来说,这通常不是必需的。但其对某些组件,尤其是可重用的组件库是很有用的。
就像上述所说,在未涉及到组件化或者复杂交互式基本用不到ref,BUT,这怎么可能呢!!!
对于组件复用的情况,总会有你需要子组件里的方法调用或者状态返回的时候,那么这时候你就需要获取组件的一些属性了,对此在面对不同项目时,ref的创建还是有所不同的;
1. 看下使用场景:
- 需要获取子组件方法或状态 (这种情况最为多见)
- 需要获取子组件DOM元素相关信息时
- 需要获取子组件聚焦或失焦状态时
2. ref 的5种创建方式
1). 类组件
- 最为粗暴的方式calback(this)
// 父组件
import React, { Component } from "react";
import Child1 from "./Child1";
class Index extends Component {
constructor(props) {
super(props);
this.state = {
childRef: null,
};
}
callback = (childRef) => {
// 存储子组件实例 想要用什么怎么用不就为所欲为了
this.setState({ childRef });
};
render() {
return (
<Child1 childRef={this.callback} />
);
}
}
export default Index;
// 子组件
import React, { Component } from "react";
class Index extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
// 将其子组件的this实例直接返回
this.props.childRef(this);
}
render() {
return (
<div className="border">
<h3>child1</h3>
</div>
);
}
}
export default Index;
- 高阶组件wrappedComponentRef
// 父组件这样写
<Child2 wrappedComponentRef={(ref) => {
this.childRef = ref
}} />
// 子组件为高阶组件
// 装饰器或者包裹或等等
@Form.create()
class Index extends Component {
- 官网推荐 React.createRef()
// 父组件---获取子组件实例
const ref = React.createRef();
<Child3 ref={ref} />
2).函数组件
- React.useRef()
// 获取DOM元素实例
const Index = () => {
const ref4 = useRef();
const handleClick = () => {
console.log(ref4, "child4");
};
return (
<div>
<Button ref={ref4} onClick={handleClick}>点击</Button>
</div>
);
};
- React.useImperativeHandle()
// 父组件
const ref4 = useRef();
<Child4 ref={ref4} />
//子组件
import React, { useImperativeHandle } from "react";
const Index = React.forwardRef((props, ref) => {
// 这里返回的对象就是父组件创建的ref4实例,需要的方法或者属性直接注册即可
useImperativeHandle(ref, () => ({
a: 1,
}));
return (
<div className="border">
<h3>child4</h3>
</div>
);
});
export default Index;
以上便是ref的几种创建方式,对于ref 的每次使用都要查相关资料,很是苦恼呀,于是乎就有了这篇关于ref的纯干货,不管你是面对class的老项目,还是hook的新项目应该都可以帮到你。