olefrank
olefrank

Reputation: 6820

State not updated after successful AJAX request

I'm doing a basic React app with data coming from my api. But the state is not updated when I do this.setState({}) after AJAX success. The state.events is empty in the render method.

What am I doing wrong?

import React, {PropTypes, Component} from 'react';
import axios from 'axios';
import './App.css';


class App extends Component {

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

    componentDidMount() {
        axios.get('http://localhost:4000/api/v1/events')
            .then(function (response) {
                this.setState({events: response.data});
            })
            .catch(function (error) {
                console.warn(error);
            });
    }

    render() {    
        // this.state.events keeps being an empty array []
        return (
            <div className="home">
              {
                this.state.events.map((month) => {
                  console.log(month) 
                })
              }
            </div>
        );
    }
}

export default App;

Upvotes: 2

Views: 668

Answers (3)

Praveen
Praveen

Reputation: 408

this

inside callback doesn't refer to your component context for that you need to bind your callback function of axios with your react component to update state of that component

import React, {PropTypes, Component} from 'react';
import axios from 'axios';
import './App.css';


class App extends Component {

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

componentDidMount() {
    axios.get('http://localhost:4000/api/v1/events')
        .then(function (response) {
            this.setState({events: response.data});
        }.bind(this)) // binding of callback to component
        .catch(function (error) {
            console.warn(error);
        });
}

render() {    
    // this.state.events keeps being an empty array []
    return (
        <div className="home">
          {
            this.state.events.map((month) => {
              console.log(month) 
            })
          }
        </div>
    );
}

}

Upvotes: 0

Mayank Shukla
Mayank Shukla

Reputation: 104529

The way you are using should throw the error, check the console. You need to bind the context to use this keyword inside callback method that you are using in .then, Use this:

componentDidMount() {
    axios.get('http://localhost:4000/api/v1/events')
        .then( response => {
            console.log('data', response.data);
            this.setState({events: response.data});
        })
        .catch(function (error) {
            console.warn(error);
        });
}

or use .bind(this) to bind the context, like this:

componentDidMount() {
    axios.get('http://localhost:4000/api/v1/events')
        .then(function (response) {
            this.setState({events: response.data});
        }.bind(this))
        .catch(function (error) {
            console.warn(error);
        });
}

Upvotes: 2

Shubham Khatri
Shubham Khatri

Reputation: 282080

You need to bind axios success function to the correct context to make use of setState. USe this

componentDidMount() {
        axios.get('http://localhost:4000/api/v1/events')
            .then(function (response) {
                this.setState({events: response.data});
            },bind(this))
            .catch(function (error) {
                console.warn(error);
            });
    }

Upvotes: 1

Related Questions