realsimonburns
realsimonburns

Reputation: 105

SetState Is Not A Function on OnChange

Working to get a slider to change the value of "text" in the React state.

Keep getting an error:

"App.js:90 Uncaught TypeError: this.setState is not a function" despite my best troubleshooting efforts.

What could the fix be?

  class App extends Component {
  constructor(props) {
      super(props);
      this.state = {list: [{x: "Before Pool", y:85000}, {x: "After Pool", y:82000}], text: 0, options: {bathrooms:'', bedrooms:'', sqft:''}};
    }

  componentDidMount() {
        setTimeout(() => {
         this.setState({list: [{x: "Before Pool", y:60000}, {x: "After Pool", y:30000}]});
         console.log("testing", this.state.text);
       }, 2000) ;
  }
  handleChange (event) {
    console.log("from handle change", event);
   this.setState({text : event });
  }
  render() {
    return (
      <div className="App">
          <div>
             <div style={wrapperStyle}>
               <p># of Bathrooms</p>
               <Slider min={0} max={20} defaultValue={3} onChange={this.handleChange} />
             </div>

enter image description here enter image description here

Upvotes: 1

Views: 5314

Answers (4)

Cdca
Cdca

Reputation: 11

You need to bind the handleChangemethod here

<Slider min={0} max={20} defaultValue={3} onChange={this.handleChange} />

This should look like this

<Slider min={0} max={20} defaultValue={3} onChange={this.handleChange.bind(this)} />

Or you can simply use Arrow Functions in the signature of the method, is better to use this all the time to save you to bind all the time. It should look like this:

handleChange = event => {
    console.log("from handle change", event);
    this.setState({text : event });
  }

Upvotes: 1

Mario
Mario

Reputation: 36497

The answer is pretty simple: You're looking at the wrong this.

Since you're writing a callback in a closure it's important to know that you can't access the this from outside. It always refers to the current context.

As a workaround, define your own variable (typically called self) to use inside the closure:

componentDidMount() {
    var self = this; // copy the reference
    setTimeout(() => {
        self.setState({list: [{x: "Before Pool", y:60000}, {x: "After Pool", y:30000}]});
        console.log("testing", this.state.text);
    }, 2000) ;
}

Upvotes: 1

httpNick
httpNick

Reputation: 2624

You need to bind your state to the callback within setTimeout since you are in a different context. I belive this would do the trick:

setTimeout(() => {
 this.setState({list: [{x: "Before Pool", y:60000}, {x: "After Pool", y:30000}]});
 console.log("testing", this.state.text);
   }.bind(this), 2000) ;

Upvotes: 1

Md.Estiak Ahmmed
Md.Estiak Ahmmed

Reputation: 1593

you need to bind the handleChange method

<Slider min={0} max={20} defaultValue={3} onChange={this.handleChange.bind(this)}

Upvotes: 5

Related Questions