0

I was getting an error that state was undefined in this component class method although it was set.

// searchState undefined error
fetchSearchImages() {
    const { searchStart, count, term, searchImages } = this.state;
    this.setState({
      searchStart: searchStart + count
    });
    axios
      .get(`/api/photos/search?term=${term}&count=${count}&start=${searchStart}`)
      .then(res =>
        this.setState({
          searchImages: searchImages.concat(res.data.results)
        })
      );
  }

error

However, changing it to an arrow function (class field declaration syntax) resolved the error and my code worked as expected.

// No more error
fetchSearchImages = () => {
    const { searchStart, count, term, searchImages } = this.state;
    this.setState({
      searchStart: searchStart + count
    });
    axios
      .get(`/api/photos/search?term=${term}&count=${count}&start=${searchStart}`)
      .then(res =>
        this.setState({
          searchImages: searchImages.concat(res.data.results)
        })
      );
  }

Why can't I use ES6 class method shorthand for this? My guess is it's something to do with having to bind, but I didn't know I needed to bind in that scenario.

nCardot
  • 5,992
  • 6
  • 47
  • 83
  • 1
    https://stackoverflow.com/questions/58904200/this-keyword-in-reactjs-and-why-we-loose-the-context/58904231#58904231 – Saurabh Yadav Nov 20 '19 at 05:31
  • 1
    If you look up the difference between the `this` keyword in regular vs arrow functions, as well as regular functions with bind vs arrow functions in React components, you'll find in depth explanations as to why this is the case. The short answer is because in the traditional function declaration, `this` refers to the function itself, so you have to _bind_ `this` in the constructor. Where with arrow functions, `this` context is preserved, so `this` refers to the component itself. – Jayce444 Nov 20 '19 at 05:31

3 Answers3

1

It has to do with the scope of this when you use an arrow function this will be scoped to the component class and not the function itself. So if you want to use a normal function you will need to bind the function in your react components constructor like this.fetchSearchImagesBound = this.fetchSearchImages.bind(this)

deowk
  • 4,280
  • 1
  • 25
  • 34
0

you are setStateing the state variable, you need to bind that method(this.fetchSearchImages.bind(this)) or use arrow function

0

In your first code:

fetchSearchImages = () => {
const { searchStart, count, term, searchImages } = this.state;
this.setState({
  searchStart: searchStart + count
});

Here "this" refers to this of function fetchSearchImages, not your component's this.

When you do this:

fetchSearchImages = () => {
const { searchStart, count, term, searchImages } = this.state;
this.setState({
  searchStart: searchStart + count
});

HEre "this" refers to "this" of your component because arrow function does not have it's own "this". That's why you have to use arrow function to access "this"

Rahul
  • 108
  • 1
  • 8