5

Some background: I'm trying to consume a custom web component in a react app and trying to listen to events from the web component. I believe you can't just handle the events in the usual react way on custom web component.

i.e.

<custom-button onClick={this.clickHandler}></custom-button>.  

I have tried this and it didn't work.

The problem: So, I'm trying to listen to an event via addEventListener as you would do in vanilla js but the event handler is never getting called.

An example of this is below. I know <button/> isn't a custom web component but it demonstrates the problem:

import React, { Component } from "react";

class App extends Component {
  constructor(props) {
    super(props);
    this.buttonRef = React.createRef();
  }
  componentDidMount() {
    // there are no errors attaching the handler
    this.buttonRef.current.addEventListener("onClick", e => {
      // this point is never reached
      debugger;
      console.log("onClick", e);
    });
  }
  render() {
    return <button ref={this.buttonRef}>click me</button>;
  }
}

export default App;

Any help would be appreciated.

Carl Rippon
  • 4,553
  • 8
  • 49
  • 64

4 Answers4

11

The event is called click, not onClick.

xehpuk
  • 7,814
  • 3
  • 30
  • 54
4

You don't need to use an eventListener to do it. In ReactJS, you can use a handler to the button, like this:

import React, { Component } from "react";

class App extends Component {
  constructor(props) {
    super(props);
  }
  btnHandler = e => {
      console.log("onClick",e)
  }
  render() {
    return <button onClick={this.btnHandler}> click me </button>
  }
} 

export default App;

Take a look at the ReactJS Handling Events docs.

reisdev
  • 3,215
  • 2
  • 17
  • 38
  • First "Uncaught Error: Expected `onClick` listener to be a function, instead got a value of `string` type.", now it's "Uncaught ReferenceError: btnHandler is not defined". – xehpuk May 25 '18 at 13:35
  • was my mistake, I wrote `'btnHandler'` instead of `{btnHandler}`. change it in your code and it should work. If doesn't, try `{this.btnHandler}` – reisdev May 25 '18 at 13:38
  • @xehpuk, tested and working fine here. I edit the answer with the fixes. – reisdev May 25 '18 at 13:46
  • Yes, now it's working. You don't need to bind `this` if you don't use it in the callback though. – xehpuk May 25 '18 at 13:49
  • Yeah. Will change it to arrow function. – reisdev May 25 '18 at 13:50
0

You are mixing two functionalities here, button will only react to onClick events and your ref will only react to 'click' if the ref is clicked which it isn't. So the button currently has no functionality.

From react doc:

function CustomTextInput(props) {
  // textInput must be declared here so the ref can refer to it
  let textInput = React.createRef();

  function handleClick() {
    textInput.current.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={textInput} />

      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  );
}
bginsburg
  • 123
  • 4
0

This a solution to your problem. Hope is the right solution.

Also <button onClick={this.onClick}>click me</button>

can be written as: <button onClick={e => this.onClick({e, ...})}>click me</button>

to have access to custom props you want to pass along to your button Event Listener. In this situation you Event Listener needs to look like:

onClick = (e, ...) => { // this point is never reached debugger; console.log("onClick", e); };

Please note the ... in there needs to be a key => value pair.

import React, { Component } from "react";

export default class App extends Component {
  constructor(props) {
    super(props);
  }

  onClick = e => {
      // this point is never reached
      debugger;
      console.log("onClick", e);
  };

  render() {
    return <button onClick={this.onClick}>click me</button>;
  }
}

Also try not to use React References, unless you really need to. They are not intended to be used outside of React's core functionality.