我正在参加「掘金·启航计划」
一、使用ref获取DOM
在React的开发模式中,通常情况下不需要也是不建议去直接操作原生DOM的,但是某些特殊情况确实需要去获取到DOM进行操作,比如:
管理焦点、文本选择或者媒体播放;
触发强制动画;
集成第三方DOM库;
在React中可以通过refs获取DOM,目前有三种方式来创建refs(其中方式一已不再推荐)
方式一:传入字符串(注意:官方不推荐这种方式)
- 首先在React元素上绑定一个ref字符串
- 然后通过this.refs.xx来获取即可
此方式官方不推荐使用,此方式已经过时并在未来版本会被移除
import React, { PureComponent } from 'react'
export class App extends PureComponent {
getDOM() {
console.log(this.refs.hello)
}
render() {
return (
<div>
<h2 ref="hello">Hello World</h2>
<button onClick={e => this.getDOM()}>获取DOM</button>
</div>
)
}
}
export default App
方式二:传入一个对象
- 提前通过createRef() 创建好ref对象,如titleRef
- 将创建好的对象绑定到React元素上
- 通过this.titleRef.current来获取该DOM元素
import React, { PureComponent, createRef } from 'react'
export class App extends PureComponent {
constructor() {
super()
this.titleRef = createRef()
}
getDOM() {
console.log(this.titleRef.current)
}
render() {
return (
<div>
<h2 ref={this.titleRef}>Hello World</h2>
<button onClick={e => this.getDOM()}>获取DOM</button>
</div>
)
}
}
export default App
方式三:传入一个函数
传入一个回调函数,当元素被选然后该回调函数会被执行,并将DOM元素传入
import React, { PureComponent, createRef } from 'react'
export class App extends PureComponent {
constructor() {
super()
this.titleEl = null
}
getDOM() {
console.log(this.titleEl)
}
render() {
return (
<div>
<h2 ref={el => this.titleEl = el}>Hello World</h2>
<button onClick={e => this.getDOM()}>获取DOM</button>
</div>
)
}
}
export default App
二、使用ref获取类组件实例
ref的值根据节点类型的不同而有所不同:
当ref属性用于HTML元素时,构造函数中使用React.createRef()创建的ref接收底层DOM元素作为其current属性值;
当ref属性用于自定义class组件时,ref对象接收组件的挂载实例作为其current属性值;
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.helloRef = createRef()
}
getComponent() {
console.log(this.helloRef.current)
this.helloRef.current.test() // test...
}
render() {
return (
<div>
<HelloWorld ref={this.helloRef}/>
<button onClick={e => this.getComponent()}>获取组件实例</button>
</div>
)
}
}
export default App
三、使用ref获取函数组件的DOM
函数组件是没有组件实例的,所以无法通过ref获取函数组件的实例, 但是有些时候可能想要获取函数组件中的某个DOM元素
此时可以通过React.forwardRef,其次就是通过hooks(后续讲解)
import React, { PureComponent, createRef, forwardRef } from 'react'
const HelloWorld = forwardRef(function(props, ref) {
return (
<div>
<h1 ref={ref}>Hello Word</h1>
<h2>123</h2>
</div>
)
})
export class App extends PureComponent {
constructor() {
super()
this.helloRef = createRef()
}
getComponent() {
console.log(this.helloRef.current)
}
render() {
return (
<div>
<HelloWorld ref={this.helloRef}/>
<button onClick={e => this.getComponent()}>获取组件实例</button>
</div>
)
}
}
export default App