Reputation: 101
RangeError: Maximum call stack size exceeded Reactjs ?
code working ok but when i click last quiz showing error
RangeError: Maximum call stack size exceeded
Also Score not showing in below red mark images please help me how to solve this issue i am new for react
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Questionlist from './quiz/Questionlist.jsx';
import Scorebox from './quiz/Scorebox.jsx';
import Results from './quiz/Results.jsx';
import * as serviceWorker from './serviceWorker';
class Quiz extends React.Component {
constructor(props){
super(props);
this.state= {
questions : [
{
id: 1,
text: 'What is your name?',
choices:[
{
id: 'a',
text: 'Michael'
},
{
id: 'b',
text: 'Brand'
},
{
id: 'c',
text: 'Steven'
},
],
correct: 'b'
},
{
id: 2,
text: 'What is your mother name?',
choices:[
{
id: 'a',
text: 'Sara'
},
{
id: 'b',
text: 'Denny'
},
{
id: 'c',
text: 'senny'
},
],
correct: 'c'
},
{
id: 3,
text: 'What is your father name?',
choices:[
{
id: 'a',
text: 'Bobby'
},
{
id: 'b',
text: 'Harry'
},
{
id: 'c',
text: 'Waye'
},
],
correct: 'c'
},
{
id: 4,
text: 'What is your friend name?',
choices:[
{
id: 'a',
text: 'John'
},
{
id: 'b',
text: 'Paul'
},
{
id: 'c',
text: 'Jose'
},
],
correct: 'a'
},
],
score: 0,
current: 1
}
}
setCurrent(current){
this.setState({current});
}
setScore(score){
this.setScore({score});
}
render() {
if(this.state.current > this.state.questions.length){
var scorebox = '';
var results = <Results {...this.state} />
}else{
scorebox = <Scorebox {...this.state} />
var results = '';
}
//return <Questionlist questions={this.state.questions} />
return(
<div className="container">
<div className="row">
<div className="col-md-12">
<h1>Quiz</h1>
{scorebox}
<Questionlist {...this.state} setCurrent={this.setCurrent.bind(this)} setScore={this.setScore.bind(this)} />
{results}
</div>
</div>
</div>
)
}
}
ReactDOM.render(<Quiz />, document.getElementById('root'));
serviceWorker.unregister();
Questionlist.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import Question from './Question.jsx';
class Questionlist extends React.Component {
render() {
return(
<div className="question">
{
this.props.questions.map(question => {
//console.log(question.id);
//console.log(this.props.current);
if(question.id == this.props.current){
return <Question question={question} key={question.id} {...this.props} />
}
})
}
</div>
)
}
}
export default Questionlist
Question.jsx
import React from 'react';
import ReactDOM from 'react-dom';
class Question extends React.Component {
onChange(e){
e.preventDefault();
const {setCurrent, setScore, question} = this.props;
let selected = e.target.value;
if(selected == question.correct){
setScore(this.props.score+1);
}
setCurrent(this.props.current+1)
}
render() {
const {question} = this.props;
return(
<div className="well">
<h3>{question.text}</h3>
<hr />
<ul className="list-group">
{
this.props.question.choices.map(choice => {
return(
<li className="list-group-item" key={choice.id}>
{choice.id} <input type="radio" onChange={this.onChange.bind(this)} name={question.id} value={choice.id} /> {choice.text}
</li>
)
})
}
</ul>
</div>
)
}
}
export default Question
Scorebox.jsx
import React from 'react';
import ReactDOM from 'react-dom';
class Scorebox extends React.Component {
render() {
console.log(this.props);
return(
<div className="well">
Question {this.props.current} out of {this.props.questions.length} <span className="pull-right"><strong>Score: {this.props.score}</strong></span>
</div>
)
}
}
export default Scorebox
Results.jsx
import React from 'react';
import ReactDOM from 'react-dom';
class Results extends React.Component {
render() {
var percent = (this.props.score / this.props.questions.length * 100);
if(percent > 80){
var message = "Awesome";
}else if(percent < 80 && percent > 60){
var message = "You did ok";
}else{
var message = "You did Harriable";
}
return(
<div className="well">
<h4>You Got {this.props.score} out of {this.props.questions.length} Correct</h4>
<h1>{percent}% - {message}</h1>
<hr />
<a href="/app">Take Again</a>
</div>
)
}
}
export default Results
Upvotes: 0
Views: 688
Reputation: 14191
This method in index.js
will cause an infinite loop when you call this method on your onChange
event at Question
component ❌
setScore(score){
this.setScore({score});
}
What you want is to set the new state, not reinvoke the method ✅
setScore(score){
this.setState({score});
}
Upvotes: 2