Reputation: 4122
I am learning reactjs and built a sample app similar to the tic toe app from on reactjs official website.
When I run the app below and click on one of the choice buttons, it says Uncaught TypeError: Cannot read property 'setAnswered' of undefined
. I can't see the difference between the way I have hooked on an instance method to onClick vs the way tic toe app did it. What am I missing?
import React from 'react';
import ReactDOM from 'react-dom';
function Choice(props) {
return (
<li>
<button onClick={props.onClick}>
{props.value}
</button>
</li>
);
}
class ChoiceList extends React.Component {
constructor(props) {
super(props);
this.state = {
choices: null,
answered: false,
};
}
setAnswered() {
this.setState({
choices: this.state.choices,
answered: true});
}
renderChoice(choice) {
return <Choice key={choice} value={choice} onClick={() => this.setAnswered()}/>;
}
showData(payload) {
const answered = false;
const choices = payload.choices;
this.setState({choices: choices, answered: answered});
}
componentDidMount() {
this.showData({choices: ['Good', 'Bad']});
}
render() {
if (!this.state.choices) {
return null;
}
return (
<div id="choices">
<ul id="unsortedList">
{this.state.choices.map(this.renderChoice)}
</ul>
</div>
);
}
}
ReactDOM.render(
<Question />,
document.getElementById('root')
);
Upvotes: 1
Views: 46
Reputation: 957
This is how your constructor should be, You have to bind the 'this' context to setAnswered .
constructor(props) {
super(props);
this.setAnswered = this.setAnswered.bind(this);
this.state = {
choices: null,
answered: false,
};
}
Upvotes: 0
Reputation: 380
Append the following code to the constructor
constructor(props) {
super(props);
this.state = {
choices: null,
answered: false,
};
this.setAnswered = this.setAnswered.bind(this);
this.renderChoice = this.renderChoice.bind(this);
this.showData = this.showData.bind(this);
}
Check the link for your reference Function.prototype.bind()
Upvotes: 1
Reputation: 1672
This is because "this" is bound to the onClick function in your Choice element and not to your component class. The following should work:
renderChoice(choice) {
return <Choice key={choice} value={choice} onClick={this.setAnswered.bind(this)}/>;
}
Upvotes: 0