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.

4
  • 1
    Possible duplicate of Uncaught TypeError: Cannot read property 'setState' of undefined
    – BradByte
    Commented Dec 8, 2016 at 15:18
  • 1
    The issue is the context of this inside of the callback function.
    – BradByte
    Commented Dec 8, 2016 at 15:19
  • Not a duplicate, read edit
    – rluks
    Commented Dec 8, 2016 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
    Commented Dec 8, 2016 at 17:42

1 Answer 1

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({});
}
7
  • 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
    Commented Dec 8, 2016 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
    Commented Dec 8, 2016 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
    Commented Dec 8, 2016 at 15:37
  • yes value works, but also key={this.state.name} as attribute for input element
    – rluks
    Commented Dec 8, 2016 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
    Commented Dec 8, 2016 at 17:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.