JavaScript React Basics Understanding State Bind Event Handlers to Components

yoav green
yoav green
8,611 Points

render() binding to the class

so why from the first place i could have used "this" in the render() method? in a way it's also a custom method within the class.

Alexey Kulikov
Alexey Kulikov
11,124 Points

Hi!

I guess that is because React calls render() method on your component (instance of Counter class which extends React.Component) e.g. counterObj.render(). So React takes care of the right context of "this" inside render(). But onClick handler is called simply as a function (not as a method on counterObj). You can even pass a function that is defined outside of your component's class, to onClick="...".

1 Answer

Ezra Siton
Ezra Siton
12,624 Points

In general this:

The JavaScript this keyword refers to the object it belongs to.

https://www.w3schools.com/js/js_this.asp

React this inside render (build-in update Method):

this.state and this.props belongs to a React element = this refer to the context inside of each component class.

https://reactjs.org/docs/react-component.html#render

scope & custom methods

You extends React.Component class - incrementScore is a custom function (Not part of React.Component class like render.

Because functions in JavaScript are scoped , this inside of the custom function (Like incrementScore no longer a reference to the component class that holds the state (No reference = this- undefined = setState not working (throw error)). Read more here: https://medium.com/komenco/react-autobinding-2261a1092849

When you create a class component that extends from React.Component, any custom methods you create are not bound to the component by default. You need to bind your custom methods, so that this refers to the component instance.

incrementScore() {
    console.log(this);
}

return: undefined

VS

This code will work (this defined = refers to the counter React.component instance)

  render() {
   console.log(this);
  }

return object like:

Counter {props: {}, context: {}, refs: {}, updater: {}, state: {}, }

Common ways "fix this" for custom methods inside React.Component class :)

option 1/3 - inside render() bind function

<button className="counter-action increment" onClick={this.incrementScore.bind(this)}> + </button>

https://reactjs.org/docs/handling-events.html

option 2/3 - inside render() add arrow function lexical this

 <button className="counter-action increment" onClick={() => this.incrementScore()}> + </button>

https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4

option 3/3 - inside render() change the onClick code + change incrementScore method

In the video the next option is to change the button (remove the arrow function):

<button className="counter-action increment" onClick={this.incrementScore}> + </button>

And change the method to an arrow function

  incrementScore = () => {
    console.log(this);
  }

https://www.w3schools.com/js/js_arrow_function.asp