TypeError: Cannot read property ‘setState’ of undefined

I am trying to setState of a component after a ajax callback receives data from REST api. here’s my code for the component constructor

constructor(props) {
    super(props);
    this.state = { posts: [] };
    this.getPosts = this.getPosts.bind(this);
}

Then I have a componentDidMount method that looks like following.

componentDidMount() {
        this.getPosts();
}

Now here’s my getPosts function where I am doing the ajax request.

getPosts = () =>  {
    $.ajax({
        type: 'get',
        url: urlname,
        success: function(data) {
            this.setState( { posts: data } )
        }
    });
}

I am tying to set the State but I am getting the following error.

this.setState is not a function

Not really sure what is causing this. It would be really helpful if someone points me to the right direction. Thanks in advance.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Bind the callback function also so that this inside the callback points to the context of the React Component and not the callback function

getPosts = () =>  {
    $.ajax({
        type: 'get',
        url: urlname,
        success: (data) => {
            this.setState( { posts: data } )
        }
    });
}

or you could use bind like

getPosts = () =>  {
    $.ajax({
        type: 'get',
        url: urlname,
        success: function(data) {
            this.setState({ posts: data })
        }.bind(this)
    });
}

Method 2

The issue is related with loosing context of this.
Please try this:

let self = this;
getPosts = () =>  {
    $.ajax({
        type: 'get',
        url: urlname,
        success: function(data) {
            self.setState( { posts: data } )
        }
    });
}

or you can use bind:

getPosts = () =>  {
        $.ajax({
            type: 'get',
            url: urlname,
            success: function(data) {
                self.setState( { posts: data } )
            }
        });
    }.bind(this)

Method 3

You have to store the context into a variable as “this” reference will not be available in the callback. Try below solution:

getPosts = () =>  {
let that=this;
    $.ajax({
        type: 'get',
        url: urlname,
        success: function(data) {
            that.setState( { posts: data } )
        }
    });
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x