pus
pus

Reputation: 101

RangeError: Maximum call stack size exceeded Reactjs?

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 enter image description here

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

Answers (1)

95faf8e76605e973
95faf8e76605e973

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

Related Questions