美文网首页
react进阶-ref

react进阶-ref

作者: 5cc9c8608284 | 来源:发表于2023-08-31 17:47 被阅读0次

    ref

    一.reference: 引用

    场景:希望直接使用dom元素中的某个方法,或者希望直接使用自定义组件中的某个方法

    1. ref作用于内置的html组件,得到的将是真实的dom对象(内置的input,div等)
    import React, { useRef,Component } from 'react'
    
    export default class FocusMy extends Component {
         handleClick=()=>{
            this.refs.txt.focus()
        }
     render(){
      return (
        <div>
        <input type="text" ref='txt' />
        <button onClick={this.handleClick}>聚焦</button>
      </div>
      )
     }
    }
    
    
    
    1. ref作用于类组件,得到的将是类的实例
    import React, { useRef,Component } from 'react'
    
    class A extends Component{
      method(){
        console.log('调用了A组建的方法');
      }
      render(){
        return <h1>组件A</h1>
      }
    }
    
    export default class FocusMy extends Component {
         handleClick=()=>{
            // this.refs.txt.focus()
            if(this.refs.refA){
              this.refs.refA.method()//此处打印了 调用了A组建的方法
            }
        }
     render(){
      return (
        <div>
          <A ref='refA'></A>
        <button onClick={this.handleClick}>聚焦</button>
      </div>
      )
     }
    }
    
    
    1. ref不能作用于函数组件

    ref不再推荐使用字符串赋值,字符串赋值的方式将来可能会被移出

    目前,ref推荐使用对象或者是函数

    对象

    通过 React.createRef 函数创建

    import React, { Component } from 'react'
    
    export default class Comp extends Component {
    
        constructor(props){
            super(props);
            this.txt = React.createRef();
        }
    
        handleClick = () => {
            this.txt.current.focus();
        }
    
        render() {
            return (
                <div>
                    <input ref={this.txt} type="text" />
                    <button onClick={this.handleClick}>聚焦</button>
                </div>
            )
        }
    }
    
    

    函数

    import React, { Component } from 'react'
    
    export default class Comp extends Component {
    
        state = {
            show: true
        }
    
        handleClick = () => {
            // this.txt.focus();
            this.setState({
                show: !this.state.show
            });
        }
    
        componentDidMount() {
            console.log("didMount", this.txt);
        }
    
        getRef = el => {
            console.log("函数被调用了", el);
            this.txt = el;
        }
    
        render() {
    
            return (
                <div>
                   {/* 写法一: */}
                    {
                        this.state.show && <input ref={this.getRef} type="text" />
                    }
                    <button onClick={this.handleClick}>显示/隐藏</button>
                </div>
            )
        }
    }
    

    函数的调用时间:

    1. componentDidMount的时候会调用该函数
      1. 在componentDidMount事件中可以使用ref
    2. 如果ref的值发生了变动(旧的函数被新的函数替代),分别调用旧的函数以及新的函数,时间点出现在componentDidUpdate之前
      1. 旧的函数被调用时,传递null
      2. 新的函数被调用时,传递对象
    3. 如果ref所在的组件被卸载,会调用函数

    谨慎使用ref

    能够使用属性和状态进行控制,就不要使用ref。

    1. 调用真实的DOM对象中的方法
    2. 某个时候需要调用类组件的方法

    二.ref转发
    ref转发其实就是将父组件传过来的ref绑定到子组件内部的的某个元素或者组件身上,而不是绑定到子组件本身.

    forwardRef方法:

    1. 参数,传递的是函数组件,不能是类组件,并且,函数组件需要有第二个参数来得到ref
    2. 返回值,返回一个新的组件
      1.函数组件
    import React, { Component } from 'react'
    
    function A(props,ref){
      return <>
      <h1 ref={ref}>组件A</h1>
      <span>{props.words}</span>
      </>
    }
    const NewA=React.forwardRef(A)
    export default class FocusMy extends Component {
      refA=React.createRef();
      componentDidMount(){
        console.log(this.refA,'this.refA');
      }
      render() {
        return (
          <div>
            <NewA words='abc' ref={this.refA} />
          </div>
        )
      }
    }
    

    2.类组件

    import React, { Component } from 'react'
    class A extends Component{
      render(){
        return <>
          <h1 ref={this.props.abc}>组件A</h1>
           <span>{this.props.words}</span>
          </>
      }
    }
    const NewA=React.forwardRef((props,ref)=>{
      return <A {...props} abc={ref}></A>
    })
    export default class FocusMy extends Component {
      refA=React.createRef();
      componentDidMount(){
        console.log(this.refA,'this.refA');
      }
      render() {
        return (
          <div>
            <NewA words='abc' ref={this.refA} />
          </div>
        )
      }
    }
    

    相关文章

      网友评论

          本文标题:react进阶-ref

          本文链接:https://www.haomeiwen.com/subject/lbszmdtx.html