React ref属性

簡単に言うと、refは、実際のdom要素またはコンポーネントインスタンスの属性を取得するために使用されます。

1.作成してアクセスする

refの値は、ノードのタイプによって異なります。

  • ref 属性がHTML要素に使用される場合、  コンストラクターは、  React.createRef() 作成された  ref 基になるDOM要素をそのcurrent 属性として使用し  ます。
  • 場合は  ref 、カスタム属性のためのクラスコンポーネントはref マウントアセンブリインスタンスオブジェクトは、そのよう受け取る  current 属性。
  • 関数コンポーネントref にはインスタンスがないため、属性を使用できません  使いたい場合は特別扱いが必要です

1.1 ref = string(非推奨)

クラスCualculatorは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:実際のdom num1に対応
 * num2:実際のdom num2に対応

1.2 ref =関数(非推奨)

クラスCualculatorはReact.Componentを拡張します{ 
  add =()=> {
     let num1 = parseInt(this.num1.value)
    let num2 = parseInt(this .nu​​m2.value) 
    let result = num1 + num2
     this.result.value = result 
  } 
  // ref値が関数の場合、この関数は、仮想domが実際のdomに変換されて購入された後に実行されます。パラメーターは、実際の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()(推奨)

React.createRef()によって作成されたref属性には、次の特性があります。

refがrender 要素に渡される  と、ノードへの参照にref current 属性でアクセスでき  ます。

  • ref 属性がHTML要素に使用される  場合、  コンストラクターは、  React.createRef() 作成された  ref 基になるDOM要素をそのcurrent 属性として使用し  ます。
  • 場合は  ref 、カスタム属性のための  クラスコンポーネントはref マウントアセンブリインスタンスオブジェクトは、そのよう受け取る  current 属性。
  • 関数コンポーネントref  にはインスタンスがないため、属性使用  できません使いたい場合は特別扱いが必要です

1.3.1 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 库
 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

おすすめ

転載: www.cnblogs.com/lyt0207/p/12684036.html