Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
44
rated 0 times [  45] [ 1]  / answers: 1 / hits: 52821  / 8 Years ago, fri, december 9, 2016, 12:00:00

I'm making a primitive quiz app with 3 questions so far, all true or false. In my handleContinue method there is a call to push the users input from a radio form into the userAnswers array. It works fine for the first run of handleContinue, after that it throws an error: Uncaught TypeError: this.state.userAnswers.push is not a function(…)



import React from react

export default class Questions extends React.Component {
constructor(props) {
super(props)
this.state = {
questionNumber: 1,
userAnswers: [],
value: ''
}

this.handleContinue = this.handleContinue.bind(this)
this.handleChange = this.handleChange.bind(this)
}

//when Continue button is clicked
handleContinue() {
this.setState({
//this push function throws error on 2nd go round
userAnswers: this.state.userAnswers.push(this.state.value),
questionNumber: this.state.questionNumber + 1
//callback function for synchronicity
}, () => {
if (this.state.questionNumber > 3) {
this.props.changeHeader(this.state.userAnswers.toString())
this.props.unMount()
} else {
this.props.changeHeader(Question + this.state.questionNumber)
}
})
console.log(this.state.userAnswers)
}

handleChange(event) {
this.setState({
value: event.target.value
})
}

render() {
const questions = [
Blargh?,
blah blah blah?,
how many dogs?
]
return (
<div class=container-fluid text-center>
<h1>{questions[this.state.questionNumber - 1]}</h1>
<div class=radio>
<label class=radio-inline>
<input type=radio class=form-control name=trueFalse value=true
onChange={this.handleChange}/>True
</label><br/><br/>
<label class=radio-inline>
<input type=radio class=form-control name=trueFalse value=false
onChange={this.handleChange}/>False
</label>
<hr/>
<button type=button class=btn btn-primary
onClick={this.handleContinue}>Continue</button>
</div>
</div>
)
}
}

More From » arrays

 Answers
41

Do not modify state directly! In general, try to avoid mutation.



Array.prototype.push() mutates the array in-place. So essentially, when you push to an array inside setState, you mutate the original state by using push. And since push returns the new array length instead of the actual array, you're setting this.state.userAnswers to a numerical value, and this is why you're getting Uncaught TypeError: this.state.userAnswers.push is not a function(…) on the second run, because you can't push to a number.



You need to use Array.prototype.concat() instead. It doesn't mutate the original array, and returns a new array with the new concatenated elements. This is what you want to do inside setState. Your code should look something like this:



this.setState({
userAnswers: this.state.userAnswers.concat(this.state.value),
questionNumber: this.state.questionNumber + 1
}

[#59777] Monday, December 5, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
eanskylerg

Total Points: 524
Total Questions: 107
Total Answers: 100

Location: Colombia
Member since Mon, May 2, 2022
2 Years ago
;