{"id":1956,"date":"2020-03-20T12:00:00","date_gmt":"2020-03-20T11:00:00","guid":{"rendered":"https:\/\/kindsonthegenius.com\/blog\/build-a-quiz-app-in-react-step-by-step-with-source-codes-part-2\/"},"modified":"2026-07-05T03:24:50","modified_gmt":"2026-07-05T01:24:50","slug":"build-a-quiz-app-in-react-step-by-step-with-source-codes-part-2","status":"publish","type":"post","link":"https:\/\/kindsonthegenius.com\/blog\/build-a-quiz-app-in-react-step-by-step-with-source-codes-part-2\/","title":{"rendered":"Build a Quiz App in React \u2013 Step by Step with Source Codes ( Part 2)"},"content":{"rendered":"<p>This is\u00a0 Part two of out Quiz App Tutorial in React. Please see <a href=\"https:\/\/kindsonthegenius.com\/tempsite\/build-a-quiz-app-in-react-step-by-step-with-source-codes-part-1\/\">Part 1<\/a> if you have not.<\/p>\n<p>In this part, we would put together the various functions, states and pieces that make up the quiz. So let&#8217;s get started!<\/p>\n<p>The various part of of the code includes<\/p>\n<ul>\n<li><a href=\"#t1\">States<\/a><\/li>\n<li><a href=\"#t2\">loadQuiz()<\/a><\/li>\n<li><a href=\"#t3\">nextQuestionHandler()<\/a><\/li>\n<li><a href=\"#t4\">checkAnswer()<\/a><\/li>\n<li><a href=\"#t5\">finishHandler()<\/a><\/li>\n<li><a href=\"#t6\">componentDidMount()<\/a><\/li>\n<li><a href=\"#t6\">componentDidUpdate()<\/a><\/li>\n<li><a href=\"#t8\">render() method<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t1\">The States<\/strong><\/h5>\n<p>First, we would try to understand the states of the component. I have outlines the 6 different states i think we would need. So copy and paste the code. I will not speak on this as the comment are very clear<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">state <span style=\"color: #333333;\">=<\/span> {\n    userAnswer<span style=\"color: #333333;\">:<\/span><span style=\"color: #008800; font-weight: bold;\">null<\/span>, <span style=\"color: #888888;\">\/\/current users answer<\/span>\n    currentIndex<span style=\"color: #333333;\">:<\/span><span style=\"color: #0000dd; font-weight: bold;\">0<\/span>,  <span style=\"color: #888888;\">\/\/current questions index<\/span>\n    options<span style=\"color: #333333;\">:<\/span> [],     <span style=\"color: #888888;\">\/\/the four options<\/span>\n    quizEnd<span style=\"color: #333333;\">:<\/span> <span style=\"color: #008800; font-weight: bold;\">false<\/span>,  <span style=\"color: #888888;\">\/\/determines if it's the last question<\/span>\n    score<span style=\"color: #333333;\">:<\/span> <span style=\"color: #0000dd; font-weight: bold;\">0<\/span>,        <span style=\"color: #888888;\">\/\/holds the score<\/span>\n    disabled<span style=\"color: #333333;\">:<\/span> <span style=\"color: #008800; font-weight: bold;\">true<\/span>   <span style=\"color: #888888;\">\/\/ determines the status of the buttons<\/span>\n}\n<\/pre>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t2\">The loadQuiz() Function<\/strong><\/h5>\n<p>This function is responsible for loading\u00a0 a single question based on the currentIndex state<\/p>\n<p>So it first gets the current index which is an integer value. Then it reads the question on that index from the QuizData component. Finally, using the values it read, it updates the question, options and answer state and returns them. Of course, this changes in state is reflected in the UI as well.<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #888888;\">\/\/Component that holds the current quiz<\/span>\nloadQuiz <span style=\"color: #333333;\">=<\/span> () <span style=\"color: #333333;\">=&gt;<\/span> {\n    <span style=\"color: #008800; font-weight: bold;\">const<\/span> {currentIndex} <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">this<\/span>.state <span style=\"color: #888888;\">\/\/get the current question index<\/span>\n    <span style=\"color: #008800; font-weight: bold;\">this<\/span>.setState(() <span style=\"color: #333333;\">=&gt;<\/span> {\n        <span style=\"color: #008800; font-weight: bold;\">return<\/span> {\n            question<span style=\"color: #333333;\">:<\/span> QuizData[currentIndex].question,\n            options <span style=\"color: #333333;\">:<\/span> QuizData[currentIndex].options,\n            answer<span style=\"color: #333333;\">:<\/span> QuizData[currentIndex].answer          \n        }\n    }\n    )\n}\n<\/pre>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t3\">The nextQuestionHandler()<\/strong><\/h5>\n<p>This function is executed when the user clicks on the &#8220;Next&#8221; button.<\/p>\n<p>First, it obtains the user&#8217;s answer, the correct answer and the score. Then it increments the currentIndex. Finally, it checks if the userAnswer is equal to the correct answer and if so, increments the score. I hope this is clear as well.<\/p>\n<p>So you can type it out yourself.<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">nextQuestionHander <span style=\"color: #333333;\">=<\/span> () <span style=\"color: #333333;\">=&gt;<\/span> {\n    <span style=\"color: #008800; font-weight: bold;\">const<\/span> {userAnswer, answer, score} <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">this<\/span>.state\n    <span style=\"color: #008800; font-weight: bold;\">this<\/span>.setState({\n        currentIndex<span style=\"color: #333333;\">:<\/span> <span style=\"color: #008800; font-weight: bold;\">this<\/span>.state.currentIndex <span style=\"color: #333333;\">+<\/span> <span style=\"color: #0000dd; font-weight: bold;\">1<\/span>\n    })\n    <span style=\"color: #888888;\">\/\/Check if correct answer and increment score<\/span>\n    <span style=\"color: #008800; font-weight: bold;\">if<\/span>(userAnswer <span style=\"color: #333333;\">===<\/span> answer){\n        <span style=\"color: #008800; font-weight: bold;\">this<\/span>.setState({\n            score<span style=\"color: #333333;\">:<\/span> score <span style=\"color: #333333;\">+<\/span> <span style=\"color: #0000dd; font-weight: bold;\">1<\/span>\n        })\n    }\n}\n<\/pre>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t4\">The checkAnswer() Function<\/strong><\/h5>\n<p>This function executes when the user select an options. It simply sets the userAnswer state and then enables the next button (disabled = false)<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #888888;\">\/\/Check the answer<\/span>\ncheckAnswer <span style=\"color: #333333;\">=<\/span> answer <span style=\"color: #333333;\">=&gt;<\/span> {\n    <span style=\"color: #008800; font-weight: bold;\">this<\/span>.setState({\n        userAnswer<span style=\"color: #333333;\">:<\/span> answer,\n        disabled<span style=\"color: #333333;\">:<\/span><span style=\"color: #008800; font-weight: bold;\">false<\/span>\n    })\n}\n<\/pre>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t5\">The finishHandler() Function<\/strong><\/h5>\n<p>This function simply checks if the quiz has gotten to the last question. Then it sets the quizEnd state to true.<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">finishHandler <span style=\"color: #333333;\">=<\/span>() <span style=\"color: #333333;\">=&gt;<\/span> {\n    <span style=\"color: #008800; font-weight: bold;\">if<\/span>(<span style=\"color: #008800; font-weight: bold;\">this<\/span>.state.currentIndex <span style=\"color: #333333;\">===<\/span> QuizData.length <span style=\"color: #333333;\">-<\/span><span style=\"color: #0000dd; font-weight: bold;\">1<\/span>){\n        <span style=\"color: #008800; font-weight: bold;\">this<\/span>.setState({\n            quizEnd<span style=\"color: #333333;\">:<\/span><span style=\"color: #008800; font-weight: bold;\">true<\/span>\n        })\n    }\n}\n<\/pre>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t6\">componentDidMount() and componentDidUpdate()<\/strong><\/h5>\n<p>The first one, componentDidMount() would simply call the loadQuiz() function to load the first question once the component mounts. In this case, the currentIndex has been initialized to 0.<\/p>\n<p>componentDidUpdate() however would check if the state has changes, and if so, it loads the next question. As it loads a new question, it also sets the disabled state to true. This means that the next button would be disabled until the user selects an option.<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t8\">The render() method<\/strong><\/h5>\n<p>This is the most involving method. But I would try to explain it very clearly. I also recommend you follow with the video for a clearer understanding. This is the method that actually display the question to the output<\/p>\n<p>The first thing it does is to get all the necessary states that it requires.<\/p>\n<p>Next, it checks if the quiz has gotten to the last question. If so, it renders the results text, then tells the user his score and then displays the correct answers.<\/p>\n<p>However, if the last question has not been reached, it displays the question at the current index together with the four options. Then it responds to the following events:<\/p>\n<ul>\n<li>when an answer is selected: in this case, it executes the checkAnswer() function<\/li>\n<li>when the Next button is clicked: call the nextQuestionHandler()<\/li>\n<\/ul>\n<p>Also note the following:<\/p>\n<ul>\n<li>the four options are displayed using the map method<\/li>\n<li>conditional formatting applied to the answer buttons<\/li>\n<li>the className of the Next button<\/li>\n<\/ul>\n<p>Other aspects of the code is explained in the video<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">render() {\n    const {\n        question, options, currentIndex, userAnswer, quizEnd} = this.state \/\/get the current state\n    \n    \n    if(quizEnd) {\n        return (\n            &lt;div&gt;\n                &lt;h1&gt;Game Over. Final score is {this.state.score} points&lt;\/h1&gt;\n                &lt;p&gt;The correct Answers for the quiz are&lt;\/p&gt;\n                &lt;ul&gt;\n                    {QuizData.map((item, index) =&gt; (\n                        &lt;li className='ui floating message options'\n                            key={index}&gt;\n                                {item.answer}\n                        &lt;\/li&gt;\n                    ))}\n                &lt;\/ul&gt;\n            &lt;\/div&gt;\n        )\n    }\n            \n    return (\n        &lt;div&gt;\n            &lt;h2&gt;{question}&lt;\/h2&gt;\n            &lt;span&gt;{`Question ${currentIndex} of ${QuizData.length -1}`}&lt;\/span&gt;\n            {options.map(option =&gt; (  \/\/for each option, new paragraph\n                &lt;p key={option.id} \n                className={`ui floating message options\n                ${userAnswer === option ? \"selected\" : null}\n                `}\n                onClick= {() =&gt; this.checkAnswer(option)}\n\n                &gt;\n                    {option}\n                &lt;\/p&gt;\n            ))}\n            {currentIndex &lt; QuizData.length -1 &amp;&amp;\n            &lt;button \n            className=\"ui inverted button\"\n            disabled = {this.state.disabled}\n            onClick = {this.nextQuestionHander}\n                &gt;Next Question&lt;\/button&gt;\n            }\n                {currentIndex === QuizData.length -1 &amp;&amp;\n                &lt;button\n                className=\"ui inverted button\"\n                disabled = {this.state.disabled}\n                onClick = {this.finishHandler}\n                &gt;Finish&lt;\/button&gt;\n                }\n        &lt;\/div&gt;\n    )\n}\n<\/pre>\n<p>So complete and test the application. As I mentioned, ensure to follow with the video. Also feel free to reach me if you have any challenges!<br \/>\nCongrats for getting this far!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is\u00a0 Part two of out Quiz App Tutorial in React. Please see Part 1 if you have not. In this part, we would put &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[414],"tags":[],"class_list":["post-1956","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/comments?post=1956"}],"version-history":[{"count":1,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1956\/revisions"}],"predecessor-version":[{"id":2124,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1956\/revisions\/2124"}],"wp:attachment":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/media?parent=1956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/categories?post=1956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/tags?post=1956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}