关于react ref 的理解

203 阅读2分钟

前言:

       ref 在react中使用的频率还是挺高的,这里说说对于ref的理解。

1.定义

    ref转发:是允许某些组件接受ref,并向下传递给子组件。

  <B ref ={...} > <A />  </B>

    这里面:理解有两层含义:1.B可以接受ref ; B 还能把ref 传递给子组件A。

1.1理解B 可以接受ref

定义子组件:子组件不需要任何的处理。

class ChildA extends PureComponent {  
   add =() => {   
    console.log('可以获取子组件的方法');  
   }  
   render() {    
       return (   
            <div>        我是一个子组件      </div>  
        )  
    }
};

定义父组件:

class Parent extends PureComponent {  
    childRef = createRef(); // 创建ref  
   handleClick =() => {    
   // 拿到子组件的实例,能够获取到子组件的数据和方法等。    
    console.log('拿到子组件的实例',this.childRef)   
    console.log('拿到子组件的实例',this.childRef.current.add())  
   }  
    render () {    
       return (    
           <div>        
           <button onClick={this.handleClick}>我是父组件的按钮</button>  
          {/* 接受ref */}     
          <ChildA ref={this.childRef} />     
          </div>    
       )  
   }
 };
export default Parent;

1.2A能接受B的ref

新建一个子组件:

   把父级传进来的ref传递给子组件的一个元素上,这样就可以操作对应元素的数据和方法。

const ChildB = React.forwardRef((props,ref) => {
  // 子组件通过React.forwardRef 接收了一个ref  
   console.log('ref',ref)  
   return (    
    <input type="text" ref={ref} />  
   )
  })

修改父级组件:

class Parent extends PureComponent {  
  childB = createRef();  
   handleClick =() => {  
     // 拿到子组件的实例,能够获取到子组件的数据和方法等。 
      console.log('拿到子组件的实例',this.childB.current.focus()) 
    }  
 render () {   
    return (     
       <div>     
         <button onClick={this.handleClick}>我是父组件的按钮</button>  
        {/* 接受ref */}    
        <ChildB ref={this.childB} />    
       </div>    
     )  
  }
};export default Parent;

总结:1.ref是作为父子通信的另一种形式;2.父组件可以直接操作子组件(方法,数据,实例)。

2.函数式组件中使用ref

** 2.1父组件只要使用useRef().**

const ParentB:FC =() => { 
    const childCRef = useRef(); 
    const handleClick =() => {   
    console.log('childCRef',childCRef)  
   }; 
   return (  
      <div>  
        <button onClick={handleClick}>我是父组件的按钮</button>   
        <ChildC ref={childCRef} />  
      </div> 
   )
 };
export default ParentB;

2.2 子组件暴露一些东西给父组件

   1.函数式组件,必须通过 forwardRef 去传递

   2.暴露给父级要通过useImperativeHandle

const ChildC =forwardRef( (props,ref) => { 
    useImperativeHandle(ref,() => ({    
   // 暴露给父组件的一些方法和数据      
    click:() => {      },   
    value:'eq'  
    }));  
   return (   
      <div>  
       我是子组件   
     </div>  
 )
});

3.使用场景

 使用场景:只要记住,父级想操作子组件的方法,获取子组件的实例信息,就可以用ref;但是ref实现细节暴露给父组件,不符合封装的隐蔽性,不可见行。