Skip to content

Instantly share code, notes, and snippets.

@djds23
Last active April 3, 2016 08:19
Show Gist options
  • Select an option

  • Save djds23/78633f844ca781d8affe to your computer and use it in GitHub Desktop.

Select an option

Save djds23/78633f844ca781d8affe to your computer and use it in GitHub Desktop.
error on line 5, this.props.onAnswerChange(answer);
var AnswerClass = React.createClass({
handleChange: function (e) {
e.preventDefault();
var answer = React.findDOMNode(this.refs.answer).value.trim();
// this.props has an attr of onAnswerChange, however its value is undefined here,
// causing a Uncaught TypeError: undefined is not a function
this.props.onAnswerChange(answer);
},
render: function () {
return (
<form className="answerClass" onChange={this.handleChange}>
<input type="text" placeholder="Say something..." ref="answer"/>
</form>
);
}
});
var QuestionClass = React.createClass({
render: function () {
return (
<h3 className="questionClass">{this.props.question}</h3>
);
}
});
var QuestionAnswerClass = React.createClass({
handleSaveAnswer: function (answer) {
var questions = this.state.questions;
var answers = [answer];
this.setState({questions: questions, answers: answers});
},
getInitialState: function () {
return {questions: [], answers: []};
},
componentDidMount: function () {
this.setState({questions: ["What can you do in the next hour?"], answers: []});
},
render: function () {
var questionNodes = this.state.questions.map(function (question) {
return (
<div className="qaBox" >
<QuestionClass question={question} />
<AnswerClass onAnswerChange={this.handleSaveAnswer} />
</div>
);
});
return (
<div className="questionAnswerClass">
{questionNodes}
</div>
);
},
});
React.render(
<QuestionAnswerClass />,
document.getElementById('content')
);
@addityasingh
Copy link
Copy Markdown

With the shift of React from createClass to ES6 classes we need to handle the correct value of this to our methods on our own, as mentioned here: http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes
Change your code to have the method bounded to correct value of this in constructor:

export default class ComponentClass extends React.Component {
  constructor(props) {
      super(props);
      this._myHandler = this._myHandler.bind(this);
  }

  _myHandler(props) {
    console.log(props);
  }

  render() {
    return (
        <div className="col-xs-6 col-md-4">
            <button type="button" className="btn btn-danger" onClick={this._myHandler}><i className="fa fa-trash"> Delete</i></button>
        </div>
    )
  }
}

The no autobinding was a deliberate step from React guys for ES6 classes. Autobinding to correct context was provided with React.createClass. Details of this can be found here: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

So based on this you could also change your code as:

export default class ComponentClass extends React.Component {
  _myHandler = (props) => {
    console.log(props);
  }

  render() {
    return (
        <div className="col-xs-6 col-md-4">
            <button type="button" className="btn btn-danger" onClick={this._myHandler}><i className="fa fa-trash"> Delete</i></button>
        </div>
    )
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment