Em termos simples, ref é usado para obter os atributos de elementos dom reais ou instâncias de componentes.
1. Crie e acesse
O valor de ref varia de acordo com o tipo de nó:
- Quando um
ref
atributo é usado para um elemento HTML , o construtor usa o elemento DOM subjacenteReact.createRef()
criadoref
como seucurrent
atributo. - Quando um
ref
atributo é usado para personalizar um componente de classe , oref
objeto recebe a instância montada do componente como seucurrent
atributo. - Você não pode usar
ref
atributos nos componentes da função porque eles não têm instâncias. Se você quiser usá-lo, é necessário tratamento especial
1.1 ref = string (descontinuado)
classe Cualculator estende React.Component {
add = () => {
let num1 = parseInt (this.refs.num1.value)
deixe num2 = parseInt (este .refs.num2.value)
deixe resultado = num1 + num2
this.refs.result.value = result
}
render () {
return (
<div>
<input ref = "num1" /> + <input ref = "num2" /> <botão onClick = { this .add}> = </button> <input ref = "result" />
</div>
)
}
}
* num1: corresponde ao real dom num1
* num2: corresponde ao dom real num2
1.2 ref = function (não recomendado)
classe Cualculator estende React.Component {
add = () => {
let num1 = parseInt (this.num1.value)
deixe num2 = parseInt (este .núm2.valor)
deixe resultado = num1 + num2
this.result.value = result
}
// Quando o valor ref é uma função, essa função será executada depois que o dom virtual for convertido para o dom real e você o comprar.O parâmetro é o real dom
render () {
return (
<div>
<input ref = { instance => this .num1 = instance} /> + <input ref = { instance => this.num2 = instance} /> <botão onClick = { this .add}> = </button> <input ref = { instance => this.result = instance} />
</div>
)
}
}
1.3 ref = React.createRef () (recomendado)
O atributo ref criado por React.createRef () possui as seguintes características:
Quando ref é passado para render
o elemento in, a referência ao nó pode ser acessada no current
atributo ref .
- Quando um
ref
atributo é usado para um elemento HTML , o construtor usa o elemento DOM subjacenteReact.createRef()
criadoref
como seucurrent
atributo. - Quando um
ref
atributo é usado para personalizar um componente de classe , oref
objeto recebe a instância montada do componente como seucurrent
atributo. - Você não pode usar atributos nos componentes da função
ref
porque eles não têm instâncias. Se você quiser usá-lo, é necessário tratamento especial
1.3.1 Elemento HTML
class Cualculator extends React.Component {
constructor(){
super()
this.num1 = React.createRef() //{current:null} current在虚拟dom转为真实dom插入页面之后变成真实dom
this.num2 = React.createRef() //{current:null} current在虚拟dom转为真实dom插入页面之后变成真实dom
this.result = React.createRef() //{current:null} current在虚拟dom转为真实dom插入页面之后变成真实dom
}
add =() => {
let num1 = parseInt(this.num1.current.value)
let num2 = parseInt(this.num2.current.value)
let result = num1 +num2
this.result.current.value = result
}
//ref值是一个函数的时候,此函数会在虚拟dom转为真实dom插入页面之后执行,参数就是真实dom
render() {
return (
<div>
<input ref={this.num1} />+<input ref={this.num2}/>
<button onClick={this.add}>=</button>
<input ref={this.result}/>
</div>
)
}
}
ReactDOM.render(<Cualculator></Cualculator>,document.getElementById('root'))
dom元素作为current属性的值
1.3.2 class组件
class UserName extends React.Component{
constructor(){
super()
this.inputRef = React.createRef()
}
render(){
return (
<input ref={this.inputRef}></input>
)
}
}
class Form extends React.Component{
constructor(){
super()
this.username = React.createRef() //this.username 就是UserName组件的实例 this.username.current = new UserName()
}
getFocus = () => {
this.username.current.inputRef.current.focus() //this.username.current.inputRef.current 获取到组件对应的真实dom节点 就是 input框
}
render(){
return (
<form>
<UserName ref={this.username}/>
<button type="button" onClick={this.getFocus}>让用户名获得焦点</button>
</form>
)
}
}
组件的实例等于current属性的值
1.3.3 函数组件
ref React.createRef()会获取到一个真实dom或者是一个组件实例对象 但是函数组件没有实例,那怎么获取函数组件的ref属性,这个时候就需要特殊处理
function UserName(props,ref) {
return <input ref={ref}></input>
}
const ForwordUsername = React.forwardRef(UserName)
class Form extends React.Component{
constructor(){
super()
this.username = React.createRef() //this.username 就是ForwordUsername组件的实例 this.username.current = new ForwordUsername()
}
getFocus = () => {
this.username.current.focus() //this.username.current.inputRef.current 获取到组件对应的真实dom节点 就是 input框
}
render(){
return (
<form>
<ForwordUsername ref={this.username}/>
<button type="button" onClick={this.getFocus}>让用户名获得焦点</button>
</form>
)
}
}
React.forwardRef会穿透UserName组件,获取到input的真实dom元素。
1.4 React.forwardRef()的底层实现
function UserName(props,ref) {
return <input ref={ref}></input>
}
function forwardRef (functionComponent) {
return class extends React.Component {
render() {
return functionComponent(this.props,this.props.ref2)
}
}
}
const ForwordUsername = forwardRef(UserName) //React.forwardRef返回一个类组件,将这个类组件传给
class Form extends React.Component{
constructor(){
super()
this.username = React.createRef() //this.username 就是UserName组件的实例 this.username.current = new UserName()
}
getFocus = () => {
this.username.current.focus() //this.username.current.inputRef.current 获取到组件对应的真实dom节点 就是 input框
}
render(){
return (
<form>
<ForwordUsername ref2={this.username}/>
<button type="button" onClick={this.getFocus}>让用户名获得焦点</button>
</form>
)
}
}
它是将函数组件转换成了类组件,当然也可以直接返回一个转化之后的函数组件
function UserName(props) {
return <input ref={props.ref2}></input>
}
//函数组件没有this,可以通过
function forwardRef (functionComponent) {
return props => functionComponent(props,props.ref2)
}
const ForwordUsername = forwardRef(UserName) //React.forwardRef返回一个类组件,将这个类组件传给
class Form extends React.Component{
constructor(){
super()
this.username = React.createRef() //this.username 就是UserName组件的实例 this.username.current = new UserName()
}
getFocus = () => {
this.username.current.focus() //this.username.current.inputRef.current 获取到组件对应的真实dom节点 就是 input框
}
render(){
return (
<form>
<ForwordUsername ref2={this.username}/>
<button type="button" onClick={this.getFocus}>让用户名获得焦点</button>
</form>
)
}
}
ReactDOM.render(<Form></Form>,document.getElementById('root'))
1.5 Refs 使用场景
- 处理焦点、文本选择或者媒体的控制
- 触发必要的动画
- 集成第三方 DOM 库