zoukankan      html  css  js  c++  java
  • React Native中ref的用法(通过组件的ref属性,来获取真实的组件)

    ref是什么?
    ref是组件的特殊属性,组件被渲染后,指向组件的一个引用。可以通过组件的ref属性,来获取真实的组件。因为,组件并不是真正的DOM节点,而是存在于内存中的一种数据结构,
    称为虚拟的DOM,只有当它真正的插入文档之后,才变为真正的DOM节点。根据React的设计,所以的DOM变动都发生在虚拟DOM上,然后再将实际的部分反映到真实的DOM上--这就是 DOM DIff,它可以提高页面性能。 如何使用ref呢? ref属性的定义是在使用组件的部分,而组件的方法之类的都是在定义组件的里面就有的。render方法被调用的时候,组件就会被渲染。渲染完成之后,就可以获取这个组件实例啦,因而就可以调用组件实例里的方法或者变量啦。

    React的ref有3种用法:

    1. 字符串(已废弃)
    2. 回调函数
    3. React.createRef() (React16.3提供)

    1. 字符串

    最早的ref用法。

    1.dom节点上使用,通过this.refs[refName]来引用真实的dom节点

    1 <input ref="inputRef" /> //this.refs['inputRef']来访问

    2.类组件上使用,通过this.refs[refName]来引用组件的实例

    <CustomInput ref="comRef" /> //this.refs['comRef']来访问

    2. 回调函数

    回调函数就是在dom节点或组件上挂载函数,函数的入参是dom节点或组件实例,达到的效果与字符串形式是一样的,
    都是获取其引用。

    回调函数的触发时机:。

    1. 组件渲染后,即componentDidMount后
    2. 组件卸载后,即componentWillMount后,此时,入参为null
    3. ref改变后

    1.dom节点上使用回调函数

    1 <input ref={(input) => {this.textInput = input;}} type="text" />

    2.类组件上使用使用回调函数

    1 <CustomInput ref={(input) => {this.textInput = input;}} />

    3.可用通过props跨级传递的方式来获取子孙级dom节点或组件实例

    下面是在跨两级获取到孙级别的组件内部的dom节点

     1 function CustomTextInput(props) {
     2     return (
     3         <div>
     4             <input ref={props.inputRef} />
     5         </div>
     6     );
     7 }
     8 function Parent(props) {
     9   return (
    10     <div>
    11       My input: <CustomTextInput inputRef={props.inputRef} />
    12     </div>
    13   );
    14 }
    15 class Grandparent extends React.Component {
    16   render() {
    17     return (
    18       <Parent
    19         inputRef={el => this.inputElement = el}
    20       />
    21     );
    22   }
    23 }

    3.React.createRef()

    在React 16.3版本后,使用此方法来创建ref。将其赋值给一个变量,通过ref挂载在dom节点或组件上,该ref的current属性
    将能拿到dom节点或组件的实例
    例如

     1 class Child extends React.Component{
     2     constructor(props){
     3         super(props);
     4         this.myRef=React.createRef();
     5     }
     6     componentDidMount(){
     7         console.log(this.myRef.current);
     8     }
     9     render(){
    10         return <input ref={this.myRef}/>
    11     }
    12 }

    4.React.forwardRef

    同样是React 16.3版本后提供的,可以用来创建子组件,以传递ref。
    例如:

     1 //子组件(通过forwardRef方法创建)
     2 const Child=React.forwardRef((props,ref)=>(
     3   <input ref={ref} />
     4 ));
     5 
     6 //父组件
     7 class Father extends React.Component{
     8   constructor(props){
     9     super(props);
    10     this.myRef=React.createRef();
    11   }
    12   componentDidMount(){
    13     console.log(this.myRef.current);
    14   }
    15   render(){
    16     return <Child ref={this.myRef}/>
    17   }
    18 }

    子组件通过React.forwardRef来创建,可以将ref传递到内部的节点或组件,进而实现跨层级的引用。

    forwardRef在高阶组件中可以获取到原始组件的实例

    例如:

     1 //生成高阶组件
     2 const logProps=logProps(Child);
     3 
     4 //调用高阶组件
     5 class Father extends React.Component{
     6   constructor(props){
     7     super(props);
     8     this.myRef=React.createRef();
     9   }
    10   componentDidMount(){
    11     console.log(this.myRef.current);
    12   }
    13   render(){
    14     return <LogProps ref={this.myRef}/>
    15   }
    16 }
    17 
    18 //HOC
    19 function logProps(Component) {
    20   class LogProps extends React.Component {
    21     componentDidUpdate(prevProps) {
    22       console.log('old props:', prevProps);
    23       console.log('new props:', this.props);
    24     }
    25 
    26     render() {
    27       const {forwardedRef, ...rest} = this.props;
    28 
    29       // Assign the custom prop "forwardedRef" as a ref
    30       return <Component ref={forwardedRef} {...rest} />;
    31     }
    32   }
    33 
    34   // Note the second param "ref" provided by React.forwardRef.
    35   // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
    36   // And it can then be attached to the Component.
    37   return React.forwardRef((props, ref) => {
    38     return <LogProps {...props} forwardedRef={ref} />;
    39   });
    40 }
     1 //生成高阶组件
     2 const logProps=logProps(Child);
     3 
     4 //调用高阶组件
     5 class Father extends React.Component{
     6   constructor(props){
     7     super(props);
     8     this.myRef=React.createRef();
     9   }
    10   componentDidMount(){
    11     console.log(this.myRef.current);
    12   }
    13   render(){
    14     return <LogProps ref={this.myRef}/>
    15   }
    16 }
    17 
    18 //HOC
    19 function logProps(Component) {
    20   class LogProps extends React.Component {
    21     componentDidUpdate(prevProps) {
    22       console.log('old props:', prevProps);
    23       console.log('new props:', this.props);
    24     }
    25 
    26     render() {
    27       const {forwardedRef, ...rest} = this.props;
    28 
    29       // Assign the custom prop "forwardedRef" as a ref
    30       return <Component ref={forwardedRef} {...rest} />;
    31     }
    32   }
    33 
    34   // Note the second param "ref" provided by React.forwardRef.
    35   // We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
    36   // And it can then be attached to the Component.
    37   return React.forwardRef((props, ref) => {
    38     return <LogProps {...props} forwardedRef={ref} />;
    39   });
    40 }

    注意:
    1. ref在函数式组件上不可使用,函数式组件无实例,但是其内部的dom节点和类组件可以使用
    2. 可以通过ReactDOM.findDOMNode(),入参是一个组件或dom节点,返回值的组件对应的dom根节点或dom节点本身
       通过refs获取到组件实例后,可以通过此方法来获取其对应的dom节点
    3. React的render函数返回的是vDom(虚拟dom)

    参考:https://blog.csdn.net/liangklfang/article/details/72858295
             https://blog.csdn.net/liwusen/article/details/80009968

  • 相关阅读:
    google.guava 实现 限流
    基于 Redisson 的限流 小 demo
    TX-LCN分布式事务-- TCC事务模式(消费者模块)
    TX-LCN分布式事务-- TCC事务模式(生产者模块)
    TX-LCN分布式事务-- LCN事务模式(消费者模块)
    TX-LCN分布式事务-- LCN事务模式(生产者模块)
    TX-LCN分布式事务-- LCN事务模式(eureka模块)
    TX-LCN分布式事务-- LCN事务模式(tm模块)
    TX-LCN分布式事务--学习地址和原理介绍
    LINQ to SQL系列三 使用DeferredLoadingEnabled,DataLoadOption指定加载选项
  • 原文地址:https://www.cnblogs.com/itgezhu/p/11573845.html
Copyright © 2011-2022 走看看