Dawn17
Dawn17

Reputation: 8297

Cannot read property 'setState' of undefined even though it's defined

  constructor(props) {
    super(props);
    this.state = {
      data: [],
    }
  }

  componentWillMount() {

    axios.get('url here', {
      auth: {
        username: '    ',
        password: '   '
      }
    }).then(function(response) {
      console.log(response.data.value)
      this.setState({
        data: response
      })
    }).catch(function(error) {
      console.log(error)
    }) 

  }
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <ul>
        { this.state.data.map(person => <li>{person.name}</li>)}
      </ul>
      </div>
    );
  }
}

When my componentWillMount runs, the console log exactly prints out what I want. However, in my setState, it says Cannot read property 'setState' of undefined even though it's defined. Why is it giving this error although the data is defined?

Upvotes: 0

Views: 36

Answers (1)

Arup Rakshit
Arup Rakshit

Reputation: 118261

It is because this is different inside .then(function() {}). Try, .then(function() {}.bind(this)), or pass arrow function like

axios.get('url here', {
    auth: {
        username: '    ',
        password: '   '
    }
}).then(response=>{
    console.log(response.data.value)
    this.setState({
        data: response
    })
}
).catch(error=>{
    console.log(error)
})

Demo code:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import axios from "axios";


class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
  }

  componentDidMount() {
    axios.get("https://jsonplaceholder.typicode.com/todos").then(
      function(resp) {
        console.log(resp);
        this.setState({ data: resp.data });
      }.bind(this)
    );
  }
  
  render() {
    return (
      <ul>
        {this.state.data.map(todo => <li key={todo.id}>{todo.title}</li>)}
      </ul>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Upvotes: 2

Related Questions