原创

react父调用被高阶组件包裹的组件的方法


具体而言,高阶组件是参数为组件,返回值为新组件的函数

https://react.docschina.org/docs/higher-order-components.html

这是一个最简易的类高阶组件

Test2.jsx(父组件)

import React, {Component} from 'react';
import Child from './child'

class Test2 extends Component {
    render() {
        return (
            <div>
                <Child/>
            </div>
        );
    }
}
export default Test2;

wrapped.jsx(高阶组件)

import React, {Component} from 'react';

const WrappedExpense = WrappedComponent => {
    class Wrapped extends Component {
        render() {
            return (
                <div>
                    <WrappedComponent {...this.props}/>
                </div>
            );
        }
    }
    return Wrapped
}

export default WrappedExpense;

child.jsx(子组件)

import React, {Component} from 'react';
import WrappedExpense from './wrapped'

@WrappedExpense
class Child extends Component {
    render() {
        return (
            <div>
                子组件
            </div>
        );
    }
}

export default Child;

父组件调用被高阶组件包裹的子组件案例

Test2.jsx(父组件)

import React, {Component} from 'react';
import Child from './child'

class Test2 extends Component {
    childRef = React.createRef()
    btnClick(){
        // this.childRef.current.childFunction() //错误
    }
    render() {
        return (
            <div>
                <button type='button' onClick={()=>this.btnClick()}>调用子组件的方法</button>
                <Child ref={this.childRef}/>
            </div>
        );
    }
}

export default Test2;

wrapped.jsx(高阶组件)

import React, {Component} from 'react';

const WrappedExpense = WrappedComponent => {
    class Wrapped extends Component {
        wrappedFunction(){
            alert("wrappedFunction")
        }
        render() {
            return (
                <div>
                    <WrappedComponent {...this.props}/>
                </div>
            );
        }
    }
    return Wrapped
}

export default WrappedExpense;

child.jsx(子组件)

import React, {Component} from 'react';
import WrappedExpense from './wrapped'

@WrappedExpense
class Child extends Component {
    childFunction(){
        alert("childFunction")
    }
    render() {
        return (
            <div>
                子组件
            </div>
        );
    }
}

export default Child;

以上案例,直接在父组件通过this.childRef.current.childFunction()调用是不可行的

解决方案

Test2.jsx(父组件)

import React, {Component} from 'react';
import Child from './child'

class Test2 extends Component {
    childRef = React.createRef()
    btnClick(){
        this.childRef.current.childFunction()
    }
    render() {
        return (
            <div>
                <button type='button' onClick={()=>this.btnClick()}>调用子组件的方法</button>
                <Child getInstance={t=>this.childRef = t}/>
            </div>
        );
    }
}

export default Test2;

child.jsx(子组件)

import React, {Component} from 'react';
import WrappedExpense from './wrapped'

@WrappedExpense
class Child extends Component {
    constructor(props) {
        super(props);
        const {getInstance} = props
        if (typeof getInstance === 'function'){
            getInstance({current: this})
        }
    }
    childFunction(){
        alert("childFunction")
    }
    render() {
        return (
            <div>
                子组件
            </div>
        );
    }
}

export default Child;

思路

定义获取实例的方法,通过props传递给子组件,子组件调用方法将实例传给父组件,父组件获取实例即可调用子组件的方法

解决方案2

Test2.jsx(父组件)

import React, {Component} from 'react';
import Child from './child'

class Test2 extends Component {
    childRef = React.createRef()
    btnClick(){
        this.childRef.current.wrappedComponentRef.current.childFunction()
    }
    render() {
        return (
            <div>
                <button type='button' onClick={()=>this.btnClick()}>调用子组件的方法</button>
                <Child ref={this.childRef}/>
            </div>
        );
    }
}

export default Test2;

wrapped.jsx(高阶组件)

import React, {Component} from 'react';

const WrappedExpense = WrappedComponent => {
    class Wrapped extends Component {
        constructor(props) {
            super(props);
            this.wrappedComponentRef = React.createRef()
        }
        wrappedFunction(){
            alert("wrappedFunction")
        }
        render() {
            return (
                <div>
                    <WrappedComponent ref={this.wrappedComponentRef} {...this.props}/>
                </div>
            );
        }
    }
    return Wrapped
}

export default WrappedExpense;

思路

在高阶组件中声明WrappedComponent的ref,使得子组件实例存在到高阶组件中,当父级的ref拿到高阶组件的实例时,同样也可以拿到子组件的实例

react
  • 作者:零三(联系作者)
  • 最后更新时间:2021-03-25 17:48
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 转载声明:来源地址 https://web03.cn
  • 评论