Reputation: 490
I am having a problem of updating a state array variable. I have looked fro many resources but none was worked.
I have Updated the code to view the full architecture of how the methods are linked to one another
This is how i defined the array in the state initially.
constructor(props) {
super(props);
this.state = {
test:[]
}
}
This is the render method. inside render method i have called to getQuizView() method
render(){
return (
<div>
{this.getQuizView()}
</div>
)
}
and inside getQuizView() method i have called to my updateArray() method
getQuizView(){
return (
<div>
{this.updateArray()}
</div>
)
}
The following method (updateArray()) is used to update the state variable.
updateArray(){
for(var i=0; i<this.props.questions.length;i++){
this.setState({ test: [...this.state.test, {id: this.props.questions[i].questionId, active: '0'}] })
}
}
But it seems like setState is happening infinitely. but this.props.questions.length = 34
Upvotes: 1
Views: 8380
Reputation: 2106
The problem is that you are updating the state in the render()
method. The render method is not supposed to have side effects, it must be purely for "rendering" your DOM.
The way react works is that whenever you update the state outside the constructor()
it calls the render method, just look at the life cycle diagram
This is a good source React component
What you are doing is while rendering you update the state(updateArray()) which in turn will cause the render function to be called again then the render function will update the state(updateArray()) and it results in an infinite loop.
[render]-> [update state(updateArray())] -> render -> [update state].....
Just remove the updateArray()
method from the render to the other life cycle hooks like componentDidMount()
if you want to show the questions just update getQuizView
getQuizView(){
return (
<div>
{this.props.questions.map((val)=>{
<div>val</div>
})
}
</div>
)
}
Upvotes: 0
Reputation: 34014
The reason it goes into inifite loop because you are doing setState in for loop never do that. What you can do is take a local array variable and assign it with this.state.test array and push objects into it. Finally do the setState outside for loop.
You can try below code to avoid infinite loop.
updateArray(){
const questions = this.state.test;
for(var i=0; i<this.props.questions.length;i++){
questions.push({'id': this.props.questions[i].questionId, 'active': '0'});
}
this.setState({
test: questions
});
}
You can even Do the same with map or forEach instead of for loop
Using .forEach:
updateArray(){
const questions = this.state.test;
this.props.questions.forEach(item => {
questions.push({'id': item.questionId, 'active': '0'});
});
this.setState({
test: questions
});
}
Using .map:
updateArray(){
const questions = this.props.questions.map(item => {
const object = {'id': item.questionId, 'active': '0'};
return obj;
});
const allQuestions = [...this.state.test, questions];
this.setState({
test: allQuestions
});
}
The difference between forEach and map is, forEach doesn’t return new array whereas map returns a new array
Upvotes: 2