2

React Error cannot read property 'onChange' of undefined The app class is calling for a map of Breakpoint components

 <Breakpoints  key={breakpoint.key}
           name={breakpoint.name}
           minWidth={breakpoint.minWidth}
           onChange={function () {   // this is where react says my error is
           this.onChange(breakpoint)
           }.bind(this)}/>

this is the parent method

`onChange(breakpoint) {
    this.props.breakpoints[breakpoint.key].name = name;
    this.state (this.state);
    console.log(breakpoint)
 }`

these are the child elements

<input type="text" name="name" defaultValue={this.state.name}  onBlur={this.onChange}/>
<input type="text" name="minWidth" defaultValue={this.state.minWidth} onBlur={this.onChange}/>

this is how I am watching and trying to update the code

onChange(e) {
    e.preventDefault();
    this.setState(
      {[e.target.name]: e.target.value},
      function () {
        console.log(this.state.name);
        this.props.onChange({
          key: this.state.key,
          name: this.state.name,
          minWidth: this.state.minWidth
        });
      }
    );
    }
1
  • are you getting this.state.name? Most likely, "this" may not be defined in that function. Commented Sep 9, 2016 at 5:03

1 Answer 1

1

The failure is in that last code snippet I believe, see the commented line I added:

onChange(e) {
e.preventDefault();
this.setState(
  {[e.target.name]: e.target.value},
  function () {
    // HERE: "this" is newly created for this function, so this.props is undefined, so this.props.onChange fires an error
    console.log(this.state.name);
    this.props.onChange({
      key: this.state.key,
      name: this.state.name,
      minWidth: this.state.minWidth
    });
  }
);
}

The fix is either wrapping that function in a bind as well, or using es2015 fat arrow functions which would require babel transpiling or the user to use only modern browsers. You could also use the var self = this trick, like so. Here are the three options:

// bind
onChange(e) {
e.preventDefault();
this.setState(
  {[e.target.name]: e.target.value},
  function () {
    console.log(this.state.name);
    this.props.onChange({
      key: this.state.key,
      name: this.state.name,
      minWidth: this.state.minWidth
    }.bind(this));
  }
);
}
// es2015 arrow functions
onChange(e) {
e.preventDefault();
this.setState(
  {[e.target.name]: e.target.value},
  () => {
    console.log(this.state.name);
    this.props.onChange({
      key: this.state.key,
      name: this.state.name,
      minWidth: this.state.minWidth
    });
  }
);
}
// self trick
onChange(e) {
e.preventDefault();
var self = this;
this.setState(
  {[e.target.name]: e.target.value},
  function () {
    console.log(self.state.name);
    self.props.onChange({
      key: self.state.key,
      name: self.state.name,
      minWidth: self.state.minWidth
    });
  }
);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.