在React中,通常情况下不建议直接操作原生DOM,但是某些特殊的情况下,确实需要获取DOM进行操作
- 管理焦点,文本选择或者媒体播放
- 触发强制动画
- 集成第三方DOM库
在React中使用ref来获取DOM对象和组件实例,ref的值根据获取的节点的类型有所不同
- 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收 DOM 元素作为其 current 属性;
- 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性;
- 不能在函数组件上使用 ref 属性,因为它们没有实例;但是通过React.forwardRef将ref转发给函数式组件中的某个DOM元素
- 当需要一个不会因为组件的重新渲染而变化的对象时,就可以使用fef
获取DOM
-
方式一:在React元素上绑定ref属性,传入一个字符串,
- 通过
this.refs.传入的字符串获取对应的元素 (已过时)
- 通过
-
方式二:在React元素上绑定ref属性,传入由React.createRef()创建的对象
- 创建的ref对象中有一个current属性就是对应的DOM对象
-
方式三:在React元素上绑定ref属性,传入一个回调函数,
- 该函数会在DOM被挂载时进行回调,这个函数会传入一个元素对象,将这个对象进行保存
import React, { PureComponent, createRef } from 'react'
export class App extends PureComponent {
constructor() {
super()
this.state = {}
this.titleRef = createRef()
this.titleEl = null
}
getNativeDOM() {
// 1.方式一: ref属性绑定一个ref字符串
console.log(this.refs.ycl)
// 2.方式二: ref属性绑定 提前创建好的ref对象, createRef()
console.log(this.titleRef.current)
// 3.方式三: ref属性绑定一个回调函数, 在对应的元素被渲染之后, 回调函数被执行, 并且将元素传入
console.log(this.titleEl)
}
render() {
return (
<div>
<h2 ref="ycl">Hello World</h2>
<h2 ref={this.titleRef}>你好,React</h2>
<h2 ref={el => this.titleEl = el}>你好啊, World</h2>
<button onClick={e => this.getNativeDOM()}>获取DOM</button>
</div>
)
}
}
export default App
获取组件实例
import React, { PureComponent, createRef } from 'react'
class HelloWorld extends PureComponent {
test() {
console.log("-----test-----")
}
render() {
return <h1>Hello World</h1>
}
}
export class App extends PureComponent {
constructor() {
super()
this.hwRef = createRef()
}
getComponent() {
console.log(this.hwRef.current)
this.hwRef.current.test()
}
render() {
return (
<div>
<HelloWorld ref={this.hwRef}/>
<button onClick={e => this.getComponent()}>获取组件实例</button>
</div>
)
}
}
export default App
ref的转发
React.forwardRef() 会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。
import React, { PureComponent, createRef, forwardRef } from 'react'
const HelloWorld = forwardRef(function(props, ref) {
return (
<div>
<h1 ref={ref}>Hello World</h1>
<p>哈哈哈</p>
</div>
)
})
export class App extends PureComponent {
constructor() {
super()
this.hwRef = createRef()
}
getComponent() {
console.log(this.hwRef.current)
}
render() {
return (
<div>
<HelloWorld ref={this.hwRef}/>
<button onClick={e => this.getComponent()}>获取组件实例</button>
</div>
)
}
}
export default App