Ref
ref的使用场景
在React的开发模式中,通常情况下不需要、也不建议直接操作DOM原生,但是某些特殊的情况,确实需要获取到DOM进行某些操作:
- 管理焦点,文本选择或媒体播放
- 触发强制动画
- 集成第三方 DOM 库
ref获取DOM元素的三种方式
ref 的值根据节点的类型而有所不同:
- 当ref 属性用于 HTML 元素时,构造函数中使用 React.createRef 创建的 ref 接收底层 DOM 元素作为其 current 属性;
- 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性;
- 你不能在函数组件上使用 ref 属性,因为他们没有实例。
在react元素上放入一个ref字符串
import React, { PureComponent } from 'react'
export default class App extends PureComponent {
getNativeDOM() {
// 在react元素上放入一个ref字符串
console.log(this.refs.haha);
}
render() {
return (
<div>
<h1 ref="haha">ref获取DOM</h1>
<button onClick={e => this.getNativeDOM()}>获取DOM</button>
</div>
)
}
}
效果如下:
创建ref对象
import React, { PureComponent, createRef } from 'react'
export default class App extends PureComponent {
constructor() {
super();
this.titleRef = createRef();
}
getNativeDOM() {
// 用createRef创建ref对象,并绑定到元素上
console.log(this.titleRef.current);
}
render() {
return (
<div>
<h1 ref="haha">ref获取DOM</h1>
<h2 ref={this.titleRef}>ref获取DOM</h2>
<button onClick={e => this.getNativeDOM()}>获取DOM</button>
</div>
)
}
}
效果如下:
⭕️ 推荐这种方式
回调函数的形式
import React, { PureComponent, createRef } from 'react'
export default class App extends PureComponent {
constructor() {
super();
this.titleRef = createRef();
}
getNativeDOM() {
// 回调函数的形式
console.log(this.title);
}
render() {
return (
<div>
<h1 ref="haha">ref获取DOM</h1>
<h2 ref={this.titleRef}>ref获取DOM</h2>
<h3 ref={el => this.title = el}>ref获取DOM</h3>
<button onClick={e => this.getNativeDOM()}>获取DOM</button>
</div>
)
}
}
效果如下:
ref获取类组件实例
采用获取元素的第二种方法:
import React, { PureComponent, createRef } from 'react'
class HelloWorld extends PureComponent {
render() {
return <h1>Hello World</h1>
}
}
export default class App extends PureComponent {
constructor() {
super();
this.helloWorldRef = createRef();
}
getNativeDOM() {
console.log(this.helloWorldRef.current);
}
render() {
return (
<div>
<HelloWorld ref={this.helloWorldRef} />
<button onClick={e => this.getNativeDOM()}>获取DOM</button>
</div>
)
}
}
效果如下:
ref获取函数式组件实例
在前面我们学习ref时讲过,ref不能应用于函数式组件,因为函数式组件没有实例,所以不能获取到对应的组件对象但是,在开发中我们可能想要获取函数式组件中某个元素的DOM,这个时候我们应该如何操作呢?
- 直接传入ref属性(❌ 错误的做法)
- 通过forwardRef高阶函数(⭕️ 正确的做法),后面我们也会学习 hooks 中如何使用ref
import React, { PureComponent, createRef, forwardRef } from 'react'
const HelloWorld = forwardRef(function (props, ref) {
return (
<div>
<h1 ref={ref}>Hello World</h1>
<h2>hahaha</h2>
</div>
)
})
export default class App extends PureComponent {
constructor() {
super();
this.helloWorldRef = createRef();
}
getNativeDOM() {
console.log(this.helloWorldRef.current);
}
render() {
return (
<div>
<HelloWorld ref={this.helloWorldRef} />
<button onClick={e => this.getNativeDOM()}>获取DOM</button>
</div>
)
}
}
效果如下:
写在最后
如果大家喜欢的话可以收藏本专栏,之后会慢慢更新,然后大家觉得不错可以点个赞或收藏一下 🌟。
博客内的项目源码在react-app
分支,大家可以拷贝下来。