1

In this component, I'm not able to call a function in the render method by going this.functionName if it's not an arrow function. Howevever, I am able to call this.setState effectively in both an arrow function and a regular function. Why is "this" different in some situations, but seemingly the same in other situations in a React component like this?

import React from 'react';

class Address extends React.Component {

state = {
    fullAddress: "5001"
}

componentDidMount() {
    this.setState({
        fullAddress: "hello"
    })
}

hello = () => {
    this.setState({
        fullAddress: "hello1"
    })
}

logMessage() {
    console.log(this.state.fullAddress);
}

 render() {
   return (
     <div className="address">
       {this.state.fullAddress}
       <input type="button" value="Log" onClick={this.hello} />
     </div>
   );
 }
}

export default Address;
Dog
  • 2,120
  • 3
  • 18
  • 50
  • 1
    to understand more about `this` and arrow function in react https://stackoverflow.com/questions/47623658/es6-code-styles-best-practices/47623945#47623945 – Aaqib Dec 04 '17 at 13:38
  • Possible duplicate of [How does the “this” keyword work?](https://stackoverflow.com/q/3127429/218196) and [How to access the correct `this` inside a callback?](https://stackoverflow.com/q/20279484/218196) and [Unable to access React instance (this) inside event handler](https://stackoverflow.com/q/29577977/218196) – Felix Kling Dec 04 '17 at 15:28

1 Answers1

3

In your example, logMessage will probably break since you need to specify your this context to it.

In this case, simply bind it in Address's constructor like so:

class Address extends Component {
  constructor(props) {
    super(props)

    this.logMessage = this.logMessage.bind(this)
  }
} 

A second approach would be the same you already used with hello as arrow function like. Arrow functions keep your current context (this) and that's why you have access to this.setState inside hello's body for example.

mersocarlin
  • 6,729
  • 1
  • 22
  • 34
  • thank you. i'm confused though, why am i able to call this.setState in both the arrow function and the regular function and have it works in both instances? shouldn't "this" be bound different in those functions such that this.setState wouldn't work in one of them? – Dog Dec 04 '17 at 13:29
  • Arrow function keeps `this` automatically for you (that's why `this.setState` works). If you don't use arrow function, like in `logMessage` you **need** to specify who is `this` (in the constructor) otherwise `this.setState` will not work. – mersocarlin Dec 04 '17 at 13:32
  • no, that's not accurate. i can call this.setState in componentDidMount above, which is a regular function, and it works fine. – Dog Dec 04 '17 at 13:34
  • It works in `componentDidMount` because your class _extends_ `React.Component`. This is a lifecycle method where your base class takes care. Whereas `logMessage` is a new event that you need to specify which `this` it's supposed to call. – mersocarlin Dec 04 '17 at 13:36
  • @Dog should you have any other question regarding this, don't hesitate to ask again :) – mersocarlin Dec 04 '17 at 13:40
  • i really appreciate your insight on this. nobody i talked to knew why it was working in that lifecycle method. – Dog Dec 04 '17 at 13:42
  • Hopefully now you also know :) Working if `this`,`bind` contexts and such is also a hard thing to grasp. – mersocarlin Dec 04 '17 at 13:44