Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react loses 'this' context inside promise [duplicate]

I am quite new with react and am probably making a silly mistake. I am trying to make an api call with axios that returns a promise. When this promise resolves I would like to pass the result of this to a function that updates state on the parent through a callback. However it appears that 'this' is gone as I get undefined. I guess as its resolved in the future there is no longer a 'this' context? I can get around it by assigning the callback to a temp and use that but it feels clumsy. Here is the code:

axios.get(url)
  .then(function(response) {
    this.props.handler(response.data.thing)
  })
  .catch(function(error) {
    console.log(error)
  })

this works:

let handler = this.props.handler
axios.get(url)
  .then(function(response) {
    handler(response.data.word)
  })
  .catch(function(error) {
    console.log(error)
  })
like image 209
user1584120 Avatar asked Dec 20 '17 08:12

user1584120


1 Answers

This is where arrow functions come in. Arrow Functions basically maintain the this from above and don't override it within the function. You can read more on the MDN. Remember it is a newer feature so some older browsers won't support it.

The following code is an example using arrow functions based on your code in your question.

axios.get(url)
  .then((response) => {
    this.props.handler(response.data.thing)
  })
  .catch((error) => {
    console.log(error)
  })

Edit:

The other way to do this without ES6 syntax is by setting a variable outside of the function. The other example you provided in your question will work even if arrow functions aren't supported. But you can also use the following code as well.

var self = this;
axios.get(url)
  .then(function (response) {
    self.props.handler(response.data.thing)
  })
  .catch(function (error) {
    console.log(error)
  })

This will let you access the correct this by using the variable created (self). Of course the downside to this as mentioned is it is slightly more clunky and not quite as clean as using an arrow function.

For more information about browser compatibility with Arrow Functions you can look at Can I use. Although if you are using React there is a good chance you could be using Babel as a compiler which should take care of converting ES6 syntax and making it more browser compatible.

like image 174
Charlie Fish Avatar answered Nov 15 '22 10:11

Charlie Fish