Search code examples
reactjssuperagent

setState from an API response using superagent and React


I get an error when trying to change the state of a component.

Uncaught TypeError: Cannot read property 'setState' of undefined

constructor(props){
    super(props);

    this.state={
        r:'',
        message:''
    };
    this.setStateMessage = this.setStateMessage.bind(this);
}
setStateMessage (e){
    e.preventDefault();
    var test = this.state.message;

    request
      .post('http://127.0.0.1:5000/api/db')
      .send({message: this.state.message})
      .accept('application/json')
      .withCredentials()
      .end(function(err, res){
        if(err)
            throw err;
        this.setState({ r: res.body.message });
      });
}

render() {
    return (
        <div>
            <div className='response'>
                {this.state.r}
            </div>
            //form with input
        </div>
    )}

Solution

  • This is because you are calling this.setState from within a function so this is actually a reference to the function you are in. You need to either store a reference to the correct this or use an arrow which does not have its own context and inherits from the parent context. So:

    setStateMessage (e){
      e.preventDefault();
      var test = this.state.message;
      var self = this;
    
      request
        .post('http://127.0.0.1:5000/api/db')
        .send({message: this.state.message})
        .accept('application/json')
        .withCredentials()
        .end(function(err, res){
          if(err) throw err;
          self.setState({ r: res.body.message });
      });
    }
    

    Or:

    setStateMessage (e){
      e.preventDefault();
      var test = this.state.message;
    
      request
        .post('http://127.0.0.1:5000/api/db')
        .send({message: this.state.message})
        .accept('application/json')
        .withCredentials()
        .end((err, res) => {
          if(err) throw err;
          this.setState({ r: res.body.message });
      });
    }