Croolsby Croolsby - 3 months ago 10
React JSX Question

What is the difference between these two declarations in react javascript?

I am using the class syntax to declare a react component:

import React, {Component} from 'react'
class Page extends Component {
constructor(props) {
super(props)
this.state = {value: ''}
}

doA(event) {this.setState({value: event.target.value})}

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

render {
return (
<input type="text" onChange={this.doB}/>

{*the following is wrong:*}
{*<input type="text" onChange={this.doA}/>*}
)
}
}


If I try to handle
onChange
using
doA
, I get this error:
TypeError: Cannot read property 'setState' of undefined
.

doA
's declaration looks more like a class method from Java, and
doB
's declaration looks more like an anonymous function assigned to a class property. I would have thought using
onChange = this.doA
would keep
this
assigned to the class, but it's the other way around.
onChange = doB
keeps
this
assigned to the class.

I tried searching for explanations but I don't know the proper terminology, thus my search terms are poor.

On a side note: If I use
onChange = doA
, I get that error, but the input field will still update correctly. So
this.state.value
is changing, yet it's giving me that error. Why is that?

Answer

Arrow functions in JavaScript lexically bind this for you. That's the reason doB works properly while doA doesn't.

If you bind doA in the constructor, things will work as expected using class syntax:

constructor(props) {
    super(props);
    this.doA = this.doA.bind(this);
}