• React ref属性


    简单来说,ref就是用来获取真实dom元素或者是组件实例的属性。

    1. 创建和访问

    ref 的值根据节点的类型而有所不同:

    • 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
    • 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
    • 不能在函数组件上使用 ref 属性,因为他们没有实例。若是想用需要经过特殊处理

    1.1 ref=字符串 (已经废弃)

    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:对应真实dom num1
     * num2:对应真实dom num2

    1.2 ref=函数 (不推荐)

    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
      }
      //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 属性用于自定义 class 组件时,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 库
    补充:

    函数组件执行完毕之后就被释放了,但是会返回一个react元素,这个元素会一直存在,最后会被渲染成真实dom

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    不积跬步无以至千里
  • 相关阅读:
    在线工具TOOL收藏
    HtmlDocument [代码碎片笔记]
    ChromiumWebBrowser [链接]
    PHP [开发汇总]
    Discuz[技术文献]
    [jvm] -- 监控和调优常用命令工具篇
    [jvm] -- 常用内存参数配置篇
    [日常摘要] -- 事务的隔离级别篇
    [日常摘要] -- ThreadLocal篇
    [日常摘要] -- zookeeper篇
  • 原文地址:https://www.cnblogs.com/lyt0207/p/12684036.html
Copyright © 2020-2023  润新知