简体   繁体   中英

How do I attach multiple event listeners to the same event of a child component from its parent component in React?

I'm creating a React component (parent) that receives a link, button, or other React component (child) as a property, and I want to attach an additional click handler to the passed-in component. This child component usually already has a click handler defined, so I can't just add onClick to it using React.cloneElement. Also, sometimes the child component's click handler prevents event propagation to the parent component, so I can't just attach the click listener to the parent and allow the event to bubble up.

Edit: The parent/child relationship and how/where the extra event listener should be attached makes this question slightly different from other questions I've seen, where the answer is to pass a callback (or array of callbacks) into the child component. I do not have access to alter the child component's API.

Here's some sample code:

export default class ParentComponent extends React.Component {
    constructor(props) {
        super();

        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(event) {
        // do something (this is not working)
    }

    render() {
        let { childComponent } = this.props;

        return (
            <div>
                {React.cloneElement(childComponent, {
                    onClick: this.handleClick
                })}
            </div>
        )
    }
}

ParentComponent.PropTypes = {
    childComponent: PropTypes.element
};

The best way I've found to do this so far uses refs and findDOMNode, as suggested in the comments above. Once you have a reference to the child component's DOM node, you can add a regular event listener when the parent component gets mounted:

export default class ParentComponent extends React.Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        this.childComponentRef.addEventListener('click', function() {
            // do something (this works!)
        }, false);
    }

    render() {
        let { childComponent } = this.props;

        return (
            <div>
                {React.cloneElement(childComponent, {
                    ref: (childComponentRef) => {
                        this.childComponentRef = ReactDOM.findDOMNode(childComponentRef);
                    }
                })}
            </div>
        )
    }
}

ParentComponent.PropTypes = {
    childComponent: PropTypes.element
};

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