In React How Can I Trigger A Custom Button's Click Event From A Different Compoennt's Event Handler?

- 1 answer

I have a React app which uses Material UI for it's interface. I've created a custom button component which styles the default Material UI button and also uses redux.

The render() function of my button component looks like this:

        return (
            <div className={classes.buttonWrapper}>
                    disabled={loading || disabled}
                        {this.buildLoader(loading, classes)}

What I want is to be able to include this button on a page and have the UI trigger its click event by other means other than clicking on it. For example, on a login form I want a user who currently has focus on the password textbox to be able to trigger the button click by hitting the Return/Enter key.

I'm sure I need to use the concept of forwarding refs in React, but I'm fairly new to React and can't get it working. You can see on my button I've defined a ref set to this.props.innerRef. My button component (called WaitingButton) is exported like this:

const withInnerRef = React.forwardRef((props, ref) => <WaitingButton 
  innerRef={ref} {...props}

var component = withStyles(styles)(withInnerRef);

export default connect(mapStateToProps, mapDispatchToProps)(component);

I've then added this button to a form like this:

            style={{marginBottom: '8px'}}
            label="A textbox!"
            onKeyPress={(e) => { if (e.key === "Enter") this.triggerClick(); }} />
            onClick={(e) => {
                console.log('Button clicked :)',;
            Press enter in textbox!

See I've assigned the button's ref and in this page's constructor I've initialised the ref in the constructor using this.submitButton = React.createRef();

Finally the triggerClick looks like this:

    triggerClick() {
        console.log('CLICK', this.submitButton.current);;

When I hit enter in the textbox, I can inspect the value assigned to this.submitButton.current and can see it is the Redux connect object that I've wrapped my button with. However, I also get the error is not a function so clearly the ref isn't getting forwarded all the way to the button itself.

I'm afraid I'm a bit lost so appealing for your help!



I just tried to reproduce your case. And I created a codesandbox for it. I think I found the problem. It seems React.forwardRef only works with prop name forwardedRef so try to rename the innerRef property to forwardedRef in your code.

const withInnerRef = React.forwardRef((props, ref) => <WaitingButton 
  forwardedRef={ref} {...props}

and also in your render() function

    disabled={loading || disabled}

You can try it with my simplified codesandbox