Dylan Czenski
Dylan Czenski

Reputation: 1365

Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined

I know that there are plenty of answers on this, for example this one. I did add the .bind(this) in the component constructor. I also tried the fat arrow method (fakeApiCall = ()=>{ ... }) but when I click Change Me, this error still displays:

enter image description here

import React, { Component } from 'react';
import axios from 'axios';
class App extends Component {

  constructor(props){
    super(props);
    this.state = {
      count : 1000
    };
    this.fakeApiCall = this.fakeApiCall.bind(this);

  }

  fakeApiCall (){
    axios.get('https://jsonplaceholder.typicode.com/users')
    .then(function(response){
    // the response comes back here successfully
      const newCount = response.data.length;
    // fail at this step
      this.setState({ count : Math.floor(newCount) });
    });
  }

  render() {
    return (
      <div className="App">
        <span style={{ fontSize : 66 }}>{this.state.count}</span>
        <input type='button' onClick={this.fakeApiCall} value='Change me' />
      </div>
    );
  }
}

export default App;

Upvotes: 1

Views: 865

Answers (1)

Treycos
Treycos

Reputation: 7492

Your fakeApiCall function is bound to your context, but the function callback in axios is not.

To solve this, you can use an arrow function, as they automatically bind with your class. You can also do it for fakeApiCall and remove it's binding :

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 1000
        };
    }

    fakeApiCall = () => {
        axios.get('https://jsonplaceholder.typicode.com/users')
            .then(response => { //This is an arrow function
                const newCount = response.data.length;
                this.setState({ count: Math.floor(newCount) });
            });
    }

    render() {
        return (
            <div className="App">
                <span style={{ fontSize: 66 }}>{this.state.count}</span>
                <input type='button' onClick={this.fakeApiCall} value='Change me' />
            </div>
        );
    }
}

Upvotes: 3

Related Questions