0

I'm starting with react and the first thing I did is to go to the main page where I see some examples, e.g.:

class MarkdownEditor extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = { value: 'Type some *markdown* here!' };
  }

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

  getRawMarkup() {
    const md = new Remarkable();
    return { __html: md.render(this.state.value) };
  }

  render() {
    return (
      <div className="MarkdownEditor">
        <h3>Input</h3>
        <textarea
          onChange={this.handleChange}
          defaultValue={this.state.value}
        />
        <h3>Output</h3>
        <div
          className="content"
          dangerouslySetInnerHTML={this.getRawMarkup()}
        />
      </div>
    );
  }
}

ReactDOM.render(<MarkdownEditor />, mountNode);

... I see that in the constructor is done:

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

What is the reason behind that? Talking with colleagues they think some possible reasons like something special behind the render() method, or something related with non supported feature of ES6.

Do someone have a specific explainment to that?

In a first look, it seems unnecessary for me as shown in this simple example:

class A {
  constructor(){
      this.a = 1;
  }
  do(){
      console.log('A', this.a);  
 }
}

class B extends A {
  constructor(){
    super();
    this.a = 2;
  }


 do(){
      console.log('B', this.a);
  }
}
console.log ((new B()).do())
  • It doesn’t really have anything to do with react or classes specifically. JavaScript has always worked like this. – Felix Kling Nov 14 '17 at 16:03
  • then the last example isn't good I guess, but I still think that I miss something inside the render() – Pablo Estornut Nov 14 '17 at 17:07
  • or how the expressions with curly braces in the markdown of react JSX are parsed – Pablo Estornut Nov 14 '17 at 17:14
  • Again, it has nothing to do with react or JSX. Have you read the answer in the duplicate? It explains why/when bind is necessary. And your last example is a perfect example for when it isn’t not: you are calling the function so you are in control of what `this` refers to. But you are not calling the event handler in the first example. Hence you have to bind it to the react component instance before it is called. – Felix Kling Nov 14 '17 at 17:22
  • aha, the thing is that we do onChange=this.foo, but props.onChange is called from other context than the component when JSX parses the nodes to React.createElement, I'm more or less right? – Pablo Estornut Nov 14 '17 at 18:25
  • 1
    Basically yes. But again, it has nothing to do with how JSX is processed. Whenever you do `var foo = obj.someMethod`, `someMethod` “looses” its connection to `obj`. This what the duplicate tries to explain. And whether you use React, JSX, angular or jquery doesn’t make a difference for that. – Felix Kling Nov 14 '17 at 18:38

3 Answers3

0

Inside React render method you need to bind the function..

import React from 'react';

export default class App React.component {
  
   constructor(){
     super();
     
  //simple binding
  this.handleSomthing2 = this.handleSomthing2.bind(this);
   
   //binding somthing with different name
  this.handleSomthing4 = this.handle.bind(this);
    
   }
handleSomthing() {
 //code here
}

handleSomthing2(){
 //code here
}



//using arrow function
handleSomthing3=()=>{// code here}

handleSomthing4(){
 //code here
}
   
 render() {
 
 return (
  <div>
   {handleSomthing()} //cannot be access without binding.
   {this. handleSomthing()} //cannot be access without binding.
  
   {this.handleSomthing2} //bind with the function above and can be access.
   
   {this.handleSomthing3} //using arrow function bind the above function.
   
   {this.handle} // this bind the function handleSomthing4
   
  </div>
 
 );
  
 } 
 
 }
mhnpd
  • 381
  • 2
  • 11
0

this.handleChange.bind(this) returns a new function, in which references to this will refer to the actual context (your React component).

When you don't bind this and pass the method to a Child component, for example. this will refer to that Child component instead of the Parent. We normally don't want to do that. That's why we bind it.

Note that arrow functions don't need that because they capture this value of the enclosing context.

Tiago Alves
  • 2,290
  • 13
  • 32
0

This code on JSX onChange={this.handleChange} is equivalent to dom.addEventListener('click', this.handleChange).

The class function this.handleChange is equivalent to A.prototype.handleChange. Which means that the prototype of A is not a instance of A.

So you need to bind this to handleChange within the scope of the instance of A.

this is depends on receiver's scope by default. See this example:

class A {
  f() {
    console.log(this);
  }
  getF() {
    return this.f;
  }
}

const a = new A();
a.f(); // A{}

const f = a.getF();
f(); // undefined

In React, lifecycle events, like componentWillMount, are called as function of the specific instance instance.componentWillMount().

sndyuk
  • 2,720
  • 2
  • 24
  • 32
  • but if we do document.addEventListener('click', this.handleChange) inside the render method, the "this" inside handleChange would be the target of the event (document) , isn't it? with the markdown of JSX that's not the case, why? – Pablo Estornut Nov 14 '17 at 17:10
  • has something to do on how the expressions between curly braces are parsed? – Pablo Estornut Nov 14 '17 at 17:11
  • @PabloEstornut: In a react component you usually want `this` to refer to the react component instance, not the target DOM element, otherwise you couldn’t call `this.setState`. I.e. you want it to be a different value than what it normally is, hence you have to explicitly change that value. – Felix Kling Nov 14 '17 at 17:25
  • @PabloEstornut Added a example code explaining a behavior of `this`. – sndyuk Nov 15 '17 at 01:30