获取 class 个 ReactElement 实例

Get class instance of ReactElement

我正在尝试获取 ReactElement 组件的实例。

我有以下(示例)代码:

import { Component, ReactElement } from "react";
import ReactDOM from "react-dom";

class Foo extends Component {
    public myAwesomeString = "meow";

    public myAwesomeFunction(echo: string) {
        console.log(echo);
    }

    public render() {
        return <span>Some content</span>;
    }
}

class Bar extends Component<{ children: ReactElement }> {
    public componentDidMount() {
        // this.props.children.myAwesomeFunction("meow") <-- How would I do this?
    }

    public render() {
        return (
            <>
                {this.props.children}
                <span>{/* this.props.children.myAwesomeString */}</span> {/* <-- And this?*/}
            </>
        );
    }
}

ReactDOM.render(
    <Bar>
        <Foo />
    </Bar>,
    document.getElementById("root")
);

FooBar 的 child 时,是否有任何方法可以从 Bar 获取实例 Foo
我试过使用 this.props.children.ref 但我刚得到 null...
有什么想法吗?

您可以使用Context注册子组件:

import { Component, ReactElement, createContext, ContextType } from "react";
import ReactDOM from "react-dom";

const RegisterContext = createContext({ register: (cp: Foo) => {} });

class Foo extends Component {
    public static contextType = RegisterContext;
    declare context: ContextType<typeof RegisterContext>;

    public componentDidMount() {
        this.context.register(this); // <--
    }

    public myAwesomeString = "meow";

    public myAwesomeFunction(echo: string) {
        console.log(echo);
    }

    public render() {
        return <span>Some content</span>;
    }
}

class Bar extends Component<{ children: ReactElement }> {
    private foo!: Foo;

    public componentDidMount() {
        this.foo.myAwesomeFunction("meow");
    }

    public registerFoo(foo: Foo) {
        this.foo = foo;
    }

    public render() {
        return (
            <>
                <RegisterContext.Provider
                    value={{ register: this.registerFoo }}>
                    {this.props.children}
                </RegisterContext.Provider>
                <span>{this.foo.myAwesomeString}</span>
            </>
        );
    }
}

ReactDOM.render(
    <Bar>
        <Foo />
    </Bar>,
    document.getElementById("root")
);

我还没有测试过这个具体的例子,但看起来它可以工作。