React ref attribute

In simple terms, ref is used to get the attributes of real dom elements or component instances.

1. Create and access

The value of ref varies according to the type of node:

  • When an  ref attribute is used for an HTML element , the constructor uses the  React.createRef() created  ref underlying DOM element as its  current attribute.
  • When an  ref attribute is used to customize a class component , the ref object receives the mounted instance of the component as its  current attribute.
  • You cannot use ref attributes on function components  because they have no instances. If you want to use it, special treatment is required

1.1 ref = string (deprecated)

class Cualculator extends React.Component {
  add =() => {
    let num1 = parseInt(this.refs.num1.value)
    let num2 = parseInt(this.refs.num2.value)
    let result = num1 +num2
    this.refs.result.value = result
  }
  render() {
    return (
      <div>
        <input ref="num1" />+<input ref="num2"/><button onClick={this.add}>=</button><input ref="result"/>
      </div>
    )
  }
}
 * num1: corresponds to the real dom num1
 * num2: corresponds to the real dom num2

1.2 ref = function (not recommended)

class Cualculator extends React.Component { 
  add = () => {
     let num1 = parseInt (this.num1.value) 
    let num2 = parseInt (this .num2.value) 
    let result = num1 + num2
     this.result.value = result 
  } 
  // When the ref value is a function, this function will be executed after the virtual dom is converted to the real dom and you buy it. The parameter is the real dom 
  render () {
     return (
       <div> 
        <input ref = { instance => this . num1 = instance} /> + <input ref = { instance => this.num2 = instance} /> <button onClick = { this .add}> = </ button> <input ref = { instance => this.result = instance}/>
      </div>
    )
  }
}

1.3 ref = React.createRef () (recommended)

The ref attribute created by React.createRef () has the following characteristics:

When ref is passed to  render the element in, the reference to the node can be accessed in the ref  current attribute.

  • When an  ref attribute is used for an  HTML element , the constructor uses the  React.createRef() created  ref underlying DOM element as its  current attribute.
  • When an  ref attribute is used to customize a  class component , the ref object receives the mounted instance of the component as its  current attribute.
  • You cannot use   attributes on function componentsref because they have no instances. If you want to use it, special treatment is required

1.3.1 Html element

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 库
 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Guess you like

Origin www.cnblogs.com/lyt0207/p/12684036.html