React 穿透获取被高级组件装饰的目标组件实例

栏目: IOS · Android · 发布时间: 5年前

内容简介:图片来源于互联网React 中常规的父子组件通信都是通过 props 进行的,子组件通过 props 来接收父组件传递的状态值以及方法,从而响应视图的更新以及事件的执行。在不同的业务场景中也会存在非常规的通信方式,例如需要在父组件中调用子组件属性或者方法,这个时候就需要获取子组件的实例来解决这个问题。
React 穿透获取被高级组件装饰的目标组件实例

图片来源于互联网

React 中常规的父子组件通信都是通过 props 进行的,子组件通过 props 来接收父组件传递的状态值以及方法,从而响应视图的更新以及事件的执行。

为什么要获取组件实例

在不同的业务场景中也会存在非常规的通信方式,例如需要在父组件中调用子组件属性或者方法,这个时候就需要获取子组件的实例来解决这个问题。

获取组件实例的方法

首先需要说明的是,只有类组件才有实例,函数式组件是没有组件实例的。

React 官方提供了 3 中使用 ref 获取实例的方式。

  1. ref 接收一个字符串作为参数 (不推荐)
class Index extends React.PureComponent {
    
        componentDidMount() {
            // 调用实例
            console.log(this.refs.classComponentInstance)
        }
        
        render() {
            return (
                <ClassComponent ref="classComponentInstance" />
            )
        }
    }
复制代码
  1. ref 接收一个回调函数作为参数
class Index extends React.PureComponent {
    
        componentDidMount() {
            // 调用实例
            console.log(this.classComponentInstance)
        }
        
        classComponentInstance = null
        
        render() {
            return (
                <ClassComponent ref={instance => {this.classComponentInstance=instance}} />
            )
        }
    }
复制代码
  1. ref 接收 React.createRef 作为参数
class Index extends React.PureComponent {
    
        componentDidMount() {
            // 调用实例
            console.log(this.classComponentInstance.current)
        }
        
        classComponentInstance = React.createRef()
        
        render() {
            return (
                <ClassComponent ref={this.classComponentInstance} />
            )
        }
    }
复制代码

被高级组件装饰的组件

所谓的高级组件也就一个函数,以组件作为参数,以组件作为返回值,主要是用于处理一些相似的逻辑,使组件可高度复用。

// Child.js
    
    @HocComponent
    export default class Child extends React.PureComponent {
        
        render(
            return (
                <div>this is Child</div>
            )
        )
    }
    
    
    // Parent.js
    
    import Child from './Child'
    
    class Parent extends React.PureComponent {
    
        childComponentInstance = null
        
        render(
            return (
                <Child ref={instance => {this.childComponentInstance=instance}} />
            )
        )
    }
    
复制代码

关于装饰符可查看教程

上面示例中 Child 就是一个被高级组件使用装饰符装饰的类组件,当在 Parent 组件中调用并使用 ref 获取其实例的时候就会发现 this.childComponentInstance 被赋值的实例并不是 Child 的实例,而是 HocComponent 组件的实例。

获取被装饰组件的实例

// Child.js
    
    @HocComponent
    export default class Child extends React.PureComponent {
    
        componentDidMount() {
            // 在 componentDidMount 周期中或者在 constructor 构造函数中执行父组件中传递过来的 getRef 方法,将实例 this 作为参数
            this.props.getRef(this)
        }
        
        render(
            return (
                <div>this is Child</div>
            )
        )
    }
    
    
    // Parent.js
    
    import Child from './Child'
    
    class Parent extends React.PureComponent {
    
        childComponentInstance = null
        
        render(
            return (
                <Child getRef={instance => {this.childComponentInstance=instance}} />
            )
        )
    }

复制代码

通过上面的方式就可以穿透高级组件,获取到目标组件的实例

抽象封装为可复用的高级组件

上面的方法虽然已经实现了我们需要的功能,但是代码侵入性太强,没有复用度可言,所以我们需要把这个功能提取出来。

// util.js
    
    export const getRef = WrapperdComponent => {
        return props => {
            const { getRef, ...otherProps }  = props
            return <WrapperdComponent ref={getRef} {...otherProps} />
        }
    }
    
复制代码

当把穿透方法提取为一个高级组件之后就可以在任何需要的地方调用即可

// 使用示例
    // Child.js
    
    import { getRef } from './util'
    
    @HocComponent
    @getRef
    export default class Child extends React.PureComponent {
        
        render(
            return (
                <div>this is Child</div>
            )
        )
    }
    
    
    
    // Parent.js
    
    import Child from './Child'
    
    class Parent extends React.PureComponent {
    
        childComponentInstance = null
        
        render(
            return (
                <Child getRef={instance => {this.childComponentInstance=instance}} />
            )
        )
    }
    
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTTP Essentials

HTTP Essentials

Stephen A. Thomas、Stephen Thomas / Wiley / 2001-03-08 / USD 34.99

The first complete reference guide to the essential Web protocol As applications and services converge and Web technologies not only assume HTTP but require developers to manipulate it, it is be......一起来看看 《HTTP Essentials》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换