3

I guess .click function comes from jquery but I saw it in pure js too so I hope I can use it in my react code too. The event where I want to use it looks like

 keyUpFunction(event) {
    console.log(event.keyCode);
    event.preventDefault();
    if(event.keyCode == 13) {
        console.log("blya");
        document.getElementsByClassName('button').click();
    };
}
...
<input onChange={this.updateMessage} onKeyUp={this.keyUpFunction} value={this.state.message} type='text' placeholder="Message" />
<button className="button"  onClick={this.submitMessage} >Submit Message</button>

The idea is after writing message I will push enter, onKeyUp will get it go to event handler and run getElementByClassName().click() and submit the message(run onClick). If I am wrong and I can't use click in react how can I implement it? both console.logs are working correctlly so the problem is in click()(I guess)

And here is the whole code

Community
  • 1
  • 1
Armen Sanoyan
  • 1,898
  • 2
  • 19
  • 32
  • my question is about click() function not about getElementByClassName should I change something in my question ? – Armen Sanoyan Apr 23 '17 at 09:32
  • 1
    instead of `document.getElementsByClassName('button').click();` why not calling that function directly by `this.submitMessage()`, it will call that function and perform the task that you want to do – Mayank Shukla Apr 23 '17 at 09:35
  • btw if you use `document.getElementById('button').click();` and define the `id ='button'` on button element it will work :) don't know why `className` is not working. – Mayank Shukla Apr 23 '17 at 09:37
  • 1
    @ArmenSanoyan: You've said it doesn't work. The linked question's answers explain why it doesn't work: There is no `click` on the **collection** of elements returned by `getElementsByClassName`, note the plural; it's on individual elements. Hence my comment above about `querySelector`, which returns an element (the first one that matches). – T.J. Crowder Apr 23 '17 at 09:37
  • @MayankShukla it doesn't work too. I am getting this error Cannot read property 'submitMessage' of undefined at keyUpFunction – Armen Sanoyan Apr 23 '17 at 09:46
  • @MayankShukla is it good practice to use getElementById in react more then ones ? – Armen Sanoyan Apr 23 '17 at 09:47
  • 1
    i think, you forgot to bind the `keyUpFunction` because of that you are getting the error, bind that method in the constructor, it will work :), it is not a good practice to use `getElementById` not even once, try to avoid all the direct dom interaction. – Mayank Shukla Apr 23 '17 at 09:49
  • @MayankShukla yea you where right! – Armen Sanoyan Apr 23 '17 at 09:52
  • @MayankShukla but I steal got this error Uncaught TypeError: Cannot read property 'click' of null – Armen Sanoyan Apr 23 '17 at 09:54
  • why you are using that, call that function directly by `this.submitMessage()` in place of that. – Mayank Shukla Apr 23 '17 at 09:55

1 Answers1

2

There are three separate problems here.

  1. You're trying to call click on the result of getElementsByClassName. That returns a collection of elements, not just one element. The click function exists on elements, not collections of them.

  2. Calling that click function on the button will not trigger React's onClick handler.*

  3. Working indirectly through the DOM is fundamentally not how you do things in React. (And it's poor practice in non-React code too.)

Instead, just call this.submitMessage from your keyup handler:

keyUpFunction(event) {
    event.preventDefault();
    if(event.keyCode == 13) {
        console.log("blya");
        this.submitMessage(event); // ****
    };
}

Simplified example:

class Input extends React.Component {
  constructor(...args) {
    super(...args);
    this.doSomething = e => {
      console.log("Do something");
    };
    this.keyup = e => {
      if (e.keyCode === 13) {
        this.doSomething(e);
      }
    };
  }
  render() {
    return (
      <div>
        <input className="button" type="text" onKeyUp={this.keyup} />
        <input type="button" onClick={this.doSomething} value="Click Me" />
      </div>
    );
  }
}

ReactDOM.render(
  <Input />,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>

* Proof of Issue #2 above, in case others are unsure (like me, until I tried it):

class Input extends React.Component {
  constructor(...args) {
    super(...args);
    this.doSomething = e => {
      console.log("Do something");
    };
    this.keyup = e => {
      if (e.keyCode === 13) {
        console.log("Calling `click`");
        document.querySelector(".button").click();
      }
    };
  }
  render() {
    return (
      <div>
        <input className="button" type="text" onKeyUp={this.keyup} />
        <input type="button" onClick={this.doSomething} value="Click Me" />
      </div>
    );
  }
}

ReactDOM.render(
  <Input />,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875