ref
reference: 引用
1、场景:希望直接使用dom元素中的某个方法,或者希望直接使用自定义组件中的某个方法
-
ref作用于内置的html组件,得到的将是真实的dom对象
import React , {Component} from"react"; export default class MyRef extends Component { getFac= (e)=> { this.refs.input.focus() } render(){ return ( <div> <input type="text" ref="input" /> <button onClick={this.getFac}>聚焦</button> </div> ) } }
-
ref作用于类组件,得到的将是类的实例
//功能 通过ref 获得的是一个 对象,然后调用对象的方法。 import React , {Component} from"react"; class Test extends Component { myMethod() { console.log("这是Test的函数") } render() { return ( <div></div> ) } } export default class MyRef extends Component { getFac= (e)=> { this.refs.input.focus(); this.refs.testComp.myMethod(); // 这里是调用类的方法 } render(){ return ( <div> <Test ref="testComp"></Test> <input type="text" ref="input" /> <button onClick={this.getFac}>聚焦</button> </div> ) } }
-
ref不能作用于函数组件
- 给函数组件 ref 没有用,因为没有意义,我们并不能通过函数得到什么,给类组件得到一个对象,给react元素,得到的DOM 对象,即使给了函数组件ref ,使用时会报错,(不能使用ref)
- 函数组件里面的react 元素是可以使用的。
2、ref不再推荐使用字符串赋值,字符串赋值的方式将来可能会被移出
-
主要原因是因为效率问题,不够灵活。
-
目前,ref推荐使用对象或者是函数
对象
通过 React.createRef 函数创建
export default class MyRef extends Component {
constructor(props) {
super(props);
this.test = React.createRef(); //创建一个 ref 对象
// 这个对象 也就是 { current : null} 那么就可以通过 { current : null} 替换 React.createRef() 也是可以的。
}
getFac= (e)=> {
console.log(this.test)
this.test.current.focus();
}
render(){
return (
<div>
<input type="text" ref={this.test} />
<button onClick={this.getFac}>聚焦</button>
</div>
)
}
}
函数
函数的调用时间:
- componentDidMount的时候会调用该函数
- 在componentDidMount事件中可以使用ref
- 如果ref的值发生了变动(旧的函数被新的函数替代),分别调用旧的函数以及新的函数,时间点出现在componentDidUpdate之前
- 旧的函数被调用时,传递null
- 新的函数被调用时,传递对象
- 如果ref所在的组件被卸载,会调用函数
谨慎使用ref (违背react 的哲学理念,是一种反模式)
能够使用属性和状态进行控制,就不要使用ref。
- 调用真实的DOM对象中的方法 (如 vedio)
- 某个时候需要调用类组件的方法
3-4、ref转发
Ref 转发是一个可选特性,其允许某些组件接收
ref
,并将其向下传递(换句话说,“转发”它)给子组件。
forwardRef
import React, { Component } from 'react'
function A(props,ref) { // 第二个参数就是转发的得到的ref
console.log(ref)
return(
<div ref={ref}>
</div>
)
}
const NewA = React.forwardRef(A) //进行转发
export default class RefTest extends Component {
ARef = React.createRef();
render() {
return (
<div>
<NewA ref={this.ARef}/>
</div>
)
}
}
forwardRef方法:
-
参数,传递的是函数组件,不能是类组件,并且,函数组件需要有第二个参数来得到ref
-
如果实在想通过类组价传递ref , 那么需要通过 prop 传递
import React, { Component } from 'react' class A extends Component { render(){ return( <h1 ref={this.props.refA}>ddd</h1> ) } } export default class RefTest extends Component { ARef = React.createRef(); render() { return ( <div> <A refA = {this.ARef}></A> // 通过属性的来传递 </div> ) } }
-
也可以通过转发,但是需要一个中间层,这个中间层就是一个函数组件。
import React, { Component } from 'react' class A extends Component { render(){ return( <h1 ref={this.props.refA}>ddd</h1> ) } } const NewA = React.forwardRef((props,ref)=>{ return ( <A {...props} refA = {ref}></A> //原理也是通过传递 props ) }) export default class RefTest extends Component { ARef = React.createRef(); render() { return ( <div> {/* <NewA ref={this.ARef}/> */} <NewA ref={this.ARef}></NewA> //这种方法 就可以使用 ref </div> ) } }
-
-
返回值,返回一个新的组件