0

I begin read the Reactjs and faced with a question in example. In constructor will add

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);

But I can't understand, what role do they play out and why are they needed? Code will work, if a method is change to the arrow func. Thanks.

Full example:

class NameForm extends React.Component {
   constructor(props) {
      super(props);
      this.state = {value: ''};

      this.handleChange = this.handleChange.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({value: event.target.value});
    }

    handleSubmit(event) {
        alert('A name was submitted: ' + this.state.value);
        event.preventDefault();
    }

    render() {
        return (
           <form onSubmit={this.handleSubmit}>
              <label>
                Name:
                   <input type="text" value={this.state.value} onChange={this.handleChange} />
               </label>
               <input type="submit" value="Submit" />
           </form>
        );
    }
   }
Denis Azi
  • 169
  • 1
  • 3
  • 9
  • 1
    Because of `this`. Have a look at https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work – Ioan Sep 09 '18 at 19:05
  • It's detaily described in [article](https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56) – xadm Sep 09 '18 at 19:21
  • Otherwise NameForm's this (including React.Component) is not passed to onChange event handler and this.setState cannot be accessed. – CuriousSuperhero Sep 09 '18 at 19:33

2 Answers2

2

Because the function will be called from the global context, so this will not refer to your class instance, it will be undefined Why ? Because when a change event occurs, React will simply call your method like this youHandler(event), you can see that the function will not have this value as it's called from the global context. I give you an example in pure javascript (outside of react scope) :

<input id="myInput" type="text" onChange="myFunction()">

<script>
 "use strict";

 function myFunction() {
   console.log(this); // this is undefined here
 }
</script>

So you need to use bind method to set the value of this, which will be equal to the current class instance

Moreover an arrow function does not have its own this; the this value of the enclosing lexical context is used when you create an arrow function. You can read the doc here So if you write :

handleChange = event => {
   this.setState({value: event.target.value});
}

you have to ask yourself the following question : What is the value of this when the handleChange function is created ? Here it will be equal to the current instance of NameForm class, and this is actually what you want.

Dónal
  • 185,044
  • 174
  • 569
  • 824
Olivier Boissé
  • 15,834
  • 6
  • 38
  • 56
  • Not true, `handleChange`'s `this` inside of the component will refer to the component context. – Ioan Sep 09 '18 at 19:38
  • yes, but when you pass the function to the `onChange` props it will be called from the global context – Olivier Boissé Sep 09 '18 at 19:39
  • We talk about calling it as `onChange={this.handleChange}` – Ioan Sep 09 '18 at 19:41
  • yes and the problem is : `this` will be undefined. Why ? because it's not called from the component context – Olivier Boissé Sep 09 '18 at 19:44
  • Is not going to be undefined. Try it. – Ioan Sep 09 '18 at 19:44
  • If you remove `this.handleChange = this.handleChange.bind(this);` it will be undefined, Look at this example https://stackblitz.com/edit/react-chdk96 – Olivier Boissé Sep 09 '18 at 19:45
  • Simple example, have a look: https://codepen.io/nataliyajurbenko/pen/JpJgmE – Ioan Sep 09 '18 at 19:47
  • Sorry, but `handleChange` from your link (example) is not an arrow function. – Ioan Sep 09 '18 at 19:48
  • 1
    But I mean creating the function without using arrow function, the author ask about why should he use `bind` or `arrow function`. I tried to explained why it's not working when using es5 function. At the end of my post, I explain why it's working using `arrow function` – Olivier Boissé Sep 09 '18 at 19:49
  • @loan The point of the question is to explain why `bind` is necessary, or why an arrow function works. Without `bind` or the arrow function `this` will not refer to the component instance; with either, it will. OP is asking why use `bind` (if not using an arrow function) etc. Olivier is explaining why `bind` is necessary if it's not an arrow function. – Dave Newton Sep 09 '18 at 21:21
0

There's no difference between them.

However, this is a part of proposed class fields for arrow functions and it isn't a ES6 feature.

Have a look at other answer.

Ioan
  • 5,152
  • 3
  • 31
  • 50
  • 1
    Using the arrow function form does not require re-binding it; that's the whole point of using an arrow function. The other difference is that using `bind` creates a new instance value based off the prototype's method while the arrow function version is always off the current instance. The `bind` here would still create a new function. – Dave Newton Sep 09 '18 at 19:16