返回
深入React源码之手写实现ref的灵魂拷问
前端
2023-11-26 11:35:02
在前端开发中,我们经常会遇到需要在组件中引用子组件实例的情况,比如我们需要访问子组件的属性或方法。在React中,可以使用ref来实现这一需求。
React的ref一共有三种形式:
- 原生组件的ref
- 类组件的ref
- 函数组件的ref
本文将按照源码思想手写实现这三种方式,带你深入理解React ref机制。
原生组件的ref
原生组件的ref是最简单的ref形式,它直接通过DOM API来访问子组件实例。
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
}
componentDidMount() {
console.log(this.childRef.current); // 输出子组件实例
}
render() {
return (
<div>
<ChildComponent ref={this.childRef} />
</div>
);
}
}
class ChildComponent extends React.Component {
render() {
return (
<div>
<h1>我是子组件</h1>
</div>
);
}
}
在父组件中,我们通过React.createRef()
创建了一个ref对象,并将它传递给子组件的ref
属性。在子组件中,我们可以通过this.props.ref
来访问父组件传递的ref对象。
类组件的ref
类组件的ref与原生组件的ref类似,不过它需要使用React.forwardRef()
来将ref传递给子组件。
const ChildComponent = React.forwardRef((props, ref) => {
return (
<div>
<h1>我是子组件</h1>
</div>
);
});
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
}
componentDidMount() {
console.log(this.childRef.current); // 输出子组件实例
}
render() {
return (
<div>
<ChildComponent ref={this.childRef} />
</div>
);
}
}
在父组件中,我们仍然通过React.createRef()
创建了一个ref对象,并将它传递给子组件的ref
属性。不过,这次我们需要使用React.forwardRef()
来将ref传递给子组件。在子组件中,我们可以通过ref
参数来访问父组件传递的ref对象。
函数组件的ref
函数组件的ref与类组件的ref类似,不过它需要使用useRef()
钩子来创建ref对象。
const ChildComponent = (props) => {
const ref = useRef(null);
return (
<div>
<h1>我是子组件</h1>
</div>
);
};
const ParentComponent = () => {
const childRef = useRef(null);
useEffect(() => {
console.log(childRef.current); // 输出子组件实例
}, []);
return (
<div>
<ChildComponent ref={childRef} />
</div>
);
};
在父组件中,我们通过useRef()
创建了一个ref对象,并将它传递给子组件的ref
属性。在子组件中,我们可以通过ref
参数来访问父组件传递的ref对象。
结语
通过本文,我们手写实现了React ref的三种形式。希望通过本文,大家能够对React ref机制有更深入的理解。