2

I have added an external script to my index.html that renders a widget inside my react component (it will render the widget where ever I wanted to. It's not a reacting component.). I'm trying to render the widget inside the id renderDivHere.

handleClick() {
  console.log("clicked on widget button")
}

render () {
  <div>
    ......
    ......
    <div id="renderDivHere" />  // the external scripts will render the widget here
    ......
  </div>
}

The widget contains some graphs, data and a button with id="wl-nav-button". I want to listen the click events in #wl-nav-button and call this.handleClick() function.

I tried jquery.click() and document.getElementById(wl-nav-button).addEventListener("click", function(){this.handleClick()});. But both are returning errors.

Help me out on this issue.

4
  • What are the errors? Commented Jun 29, 2017 at 8:51
  • Did you look up the docs? Commented Jun 29, 2017 at 8:53
  • Webpack bundling returns error. Module build failed: SyntaxError: Unexpected token, expected ( (74:10) on document.get... Commented Jun 29, 2017 at 8:53
  • @FelixHäberle checked that link. But I can't give an onClick in the element as it's creating dynamically by the widget script Commented Jun 29, 2017 at 8:55

1 Answer 1

3

Try with the following code:

componentDidMount() {
  document.addEventListener("click", this.navButtonListener);
}

componentWillUnmount() {
  document.removeEventListener("click", this.navButtonListener);
}

navButtonListener = (e) => {
  if(e.target.id == "wl-nav-button"){
    this.handleClick();
  }
}

What this does is it adds an event listener to the entire document, which is fired anytime you click. Then, a check is done to see what the clicked items id attribute is set to. If the id is your button, it fires the handleClick() function.

This also removes the event listener from your component before un-mounting it.


Demo

Here is a simple demo that just demonstrates how to add an event handler in React to something that was not rendered with React.

class MyApp extends React.Component {

  componentDidMount() {
    document.addEventListener("click", this.navButtonListener);
  }

  componentWillUnmount() {
    document.removeEventListener("click", this.navButtonListener);
  }

  navButtonListener = (e) => {
    if (e.target.id == "wl-nav-button") {
      this.handleClick();
    }
  }
  
  handleClick() {
    console.log("click!!");
  }

  render() {
    return (
      <div>
        <p>A button from a simulated external non-react library will be inserted asynchronically below:</p>
        <div id="my-container"></div>
      </div>
    );
  }
}

ReactDOM.render(<MyApp />, document.getElementById("myApp"));

//simulate a non-react library asynchronically inserting into the DOM:
setTimeout(function() {
  var button = document.createElement("BUTTON");
  var text = document.createTextNode("Click me!");
  button.appendChild(text);
  button.setAttribute("id", "wl-nav-button");
  document.getElementById("my-container").appendChild(button);
}, 2000);
<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="myApp"></div>

Sign up to request clarification or add additional context in comments.

2 Comments

working perfectly here. But returning some errors in my code. Uncaught TypeError: this.handleClick is not a function. checking the issue. Will update in some time
My bad. Made navButtonListener into an arrow function. Now working like charm. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.