简体   繁体   中英

Running method of component child from this.props.children array

import React from "react";
import ReactDOM from "react-dom";
class NestedComponent extends React.Component {
    constructor(props) {
        super(props);
        this.childMethod = this.childMethod.bind(this);
    }
    childMethod() {
        alert("Child method one ran");
    }
    render() {
        return <div>NestedComponent</div>;
    }
}
class NestedComponentTwo extends React.Component {
    constructor(props) {
        super(props);
        this.childMethod = this.childMethod.bind(this);
    }
    childMethod() {
        alert("Child method two ran");
    }
    render() {
        return <div>NestedComponentTwo</div>;
    }
}

class WrappingComponent extends React.Component {
    constructor(props) {
        super(props);
        this.runMethod = this.runMethod.bind(this);
    }
    runMethod() {
        let child = this.props.children[0];
        /** Always returns as undefined */
        //if (typeof child.childMethod == "function") {
        //    child.childMethod();
        //}
        /**
         * EDIT: Close, however the this binding seems to not be working. I can however provide the childs props to the childMethod and work with that. 
         */
        if(typeof child.type.prototype.childMethod == "funciton"){
            child.type.prototype.childMethod();
        }

    }
    render() {
        return (
            <div>
                {this.props.children}
                <button onClick={this.runMethod}>run</button>
            </div>
        );
    }
}

const App = ({}) => {
    return (
        <div>
            <WrappingComponent>
                <NestedComponent />
                <NestedComponentTwo />
            </WrappingComponent>
        </div>
    );
};

if (document.getElementById("example")) {
    ReactDOM.render(<App />, document.getElementById("example"));
}

So the goal is to have optional methods attached to a nested component that can execute from the wrapping component, almost like an event emmiter. For some reason though, the method that exists on the child component claims not to exist. However whenever I log the child component pulled from the array of the this.props.children the prototype has the method listed.

Am I missing a special way to access methods of children components through a methods variable perhaps?

Found the variable I can use to access it. If anyone has any more insight into this, or reasons why what I am doing is poor practice please let me know.

Editing the question where this is needed, but the item below is accessing the function of the child:

child.type.prototype.childMethod

Does not appear to maintain the this binding. Passing props down does work however.

You should manage all of this logic in the top level component (the App component)

 class NestedComponent extends React.Component { constructor(props) { super(props); this.childMethod = this.childMethod.bind(this); } childMethod() { alert("Child method one ran"); } render() { return <div>NestedComponent</div>; } } class NestedComponentTwo extends React.Component { constructor(props) { super(props); this.childMethod = this.childMethod.bind(this); } childMethod() { alert("Child method two ran"); } render() { return <div>NestedComponentTwo</div>; } } class WrappingComponent extends React.Component { render() { return ( <div> {this.props.children} <button onClick={this.props.onClick}>run</button> </div> ); } } class App extends React.Component { constructor(props) { super(props); this.runMethod = this.runMethod.bind(this); } runMethod() { if (this.nestedComponent) { this.nestedComponent.childMethod(); } } render() { return ( <div> <WrappingComponent onClick={this.runMethod}> <NestedComponent ref={el => this.nestedComponent = el} /> <NestedComponentTwo /> </WrappingComponent> </div> ); } }; if (document.getElementById("example")) { ReactDOM.render(<App />, document.getElementById("example")); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="example"></div> 

Moreover ref with string attribute is deprecated https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM