22

I am getting an error "TypeError: Cannot read property 'setState' of undefined" while doing a simple thing in ReactJS. I am trying to use axios to fill input with response data. So far without success. I am very new to both axios and ReactJs so it might be something very simple I overlooked?

I would expect "RESPONSE TEXT" to show up in the input field in the form after the TypeError is fixed.

This is my component:

class BasicInfoBlock extends React.Component {
    constructor(props) {
        super(props);

        this.state = { name : "EventTestName" };
    }

    componentDidMount() {
        axios
        .get(getBaseUrl()+`get`)
        .then(function (response) {
            this.setState({name: "RESPONSE TEXT"});
            //this.setState({name: response.data.name});
        })
        .catch((e) => 
        {
            console.error(e);
        });
        //this.setState({});
    }


    render(){
        return(
                <form className="form-horizontal">
                    <div className="form-group">
                        <label htmlFor="eventName" className="col-sm-2 control-label">Name</label>
                        <div className="col-sm-10">
                        <input type="text" id="eventName" className="form-control" placeholder="Event name" defaultValue={this.state.name}/>
                        </div>
                    </div>
                </form>
            );
    }
}

Thank you for your help

edit: this is not a duplicate question, this questions relates to 'this' not being available in callback. Question selected as duplicate is related to bind.

noetix
  • 4,773
  • 3
  • 26
  • 47
rluks
  • 2,762
  • 8
  • 38
  • 56
  • 1
    Possible duplicate of [Uncaught TypeError: Cannot read property 'setState' of undefined](http://stackoverflow.com/questions/32317154/uncaught-typeerror-cannot-read-property-setstate-of-undefined) – BradByte Dec 08 '16 at 15:18
  • 1
    The issue is the context of `this` inside of the callback function. – BradByte Dec 08 '16 at 15:19
  • Not a duplicate, read edit – rluks Dec 08 '16 at 16:54
  • Its the same root problem of `this` losing context when inside another function. Bind is one solution, arrows are another, using a separate var like `var self = this;` and then calling `self.setState` is another. – BradByte Dec 08 '16 at 17:42

1 Answers1

47

In your Promise's then method, this will no longer refer to the component. You could fix by using an arrow function like this:

componentDidMount() {
  axios
  .get(getBaseUrl()+`get`)
  .then((response) => {
    this.setState({name: "RESPONSE TEXT"});
    //this.setState({name: response.data.name});
  })
  .catch((e) => 
  {
    console.error(e);
  });
  //this.setState({});
}
Ben Nyberg
  • 952
  • 7
  • 13
  • Thank you, error is gone. However my input field is still not being filled in with the "RESPONSE TEXT" and I have no idea why. – rluks Dec 08 '16 at 15:30
  • 1
    @rluks You need to set the `value` prop, not `defaultValue`. To squelch the warning React will throw, you can initialise `this.state.value` with an empty string – Bojangles Dec 08 '16 at 15:37
  • You set the prop defaultValue, not value. Default value will only get set initially on mount, not when you call setState. I recommend reading the React docs about controlled components. – Ben Nyberg Dec 08 '16 at 15:37
  • yes `value` works, but also `key={this.state.name}` as attribute for input element – rluks Dec 08 '16 at 16:53
  • You don't want to use the `key` prop. That is how React identifies an element. Since your key is changing every time, your component will mount and unmount on every render. This is bad for performance and will likely cause you more trouble in the future. – Ben Nyberg Dec 08 '16 at 17:30
  • This really helped! Fantastiks – Malarivtan Sep 07 '18 at 20:51
  • I was trying to use setState inside catch with no luck. Using arrow function make it work. Thanks – yaach Jun 04 '22 at 16:21