0

I'm creating a Quiz App. Fetching MCQ Data from a .js file. I'm using a ShuffleMcq() Function to randomize options. React useState() Function keeps using that shuffle function. whenever user select an option. Which result in different selected and displayed values. How can I fix this?
Quiz Page

import React, { useState } from 'react';
import mcqContent from './mcq-content';
import shuffleMcq from '../components/shuffleMcq';

const QuizTakePage = ({match}) =>{
    const mcqData = mcqContent.find(mcqData => mcqData._id === 1);
    const optionsArray = mcqData.m_alternatives;
    const optionsCorrect = mcqData.m_alternatives[0];
    const shuffledArray = shuffleMcq(optionsArray);
    const [option, setOption] = useState();
    const handleSubmit = (e) =>{
        e.preventDefault();
        console.log(option);
        checkAnswer(option,optionsCorrect)
    }
    return(
    <>
    <h4>{mcqData.m_title}</h4>
    <form onSubmit={handleSubmit}><div className="radio"><table><tbody>
                  
    {shuffledArray.map((paragraph, key) => (
            <tr key={key}><td><label><input type="radio" name="selected_option" id="selected_option" value={paragraph} onChange={(e)=> setOption(e.target.value)}/>{paragraph}</label></td></tr>
            ))}

    </tbody></table>
    <button type="submit">Check Answer</button>
    </div></form>
    </>
    );
    

};
export default QuizTakePage;
function checkAnswer(optionVar, corr)   {

    if(optionVar==null){  console.log('Select an Answer');    }
    if(optionVar === corr) {   console.log('Answer is Correct');   }
    else{  console.log('Wrong Answer');    }
}

Shuffle Function

const shuffleMcq = function(options) {
    const array = [...options];
        let currentIndex = array.length,  randomIndex;
      
        // While there remain elements to shuffle...
        while (currentIndex !== 0) {
      
          // Pick a remaining element...
          randomIndex = Math.floor(Math.random() * currentIndex);
          currentIndex--;
      
          // And swap it with the current element.
          [array[currentIndex], array[randomIndex]] = [
            array[randomIndex], array[currentIndex]];
        }
      
        return array;
    };

export default shuffleMcq;

MCQ Content

const mcqs = [
    {
        "_id":1,
        "m_title":"Which company is the most valueable in the world?",
        "m_question":"Which company is the most valueable in the world?",
        "m_alternatives":["Apple","Google","Microsoft"],
    },

Current Result
I selected MICROSOFT as an option CheckAnswer() grab this value and return result but it display as I selected APPLE and got result for MICROSOFT. Due to useState() keeps using ShuffleMcq() Current Result Expected Result
This is the expected Result Expected Result

1 Answer 1

2

When you use setOption, file gets hoisted, so it calls the shuffledMcq and data changes. call the function on your required condition to get your result. Here I call the function on mount.

import React, { useEffect, useState } from "react";
import mcqContent from "./mcq-content";
import shuffleMcq from "./shuffleMcq";

const QuizTakePage = ({ match }) => {
  const mcqData = mcqContent.find((mcqData) => mcqData._id === 1);
  const optionsArray = mcqData.m_alternatives;
  const optionsCorrect = mcqData.m_alternatives[0];
  //   const shuffledArray = shuffleMcq(optionsArray);
  const [option, setOption] = useState("");
  const [shuffledArray, setShuffledArray] = useState([]);
  console.log("ssd");
  useEffect(() => {
    setShuffledArray(shuffleMcq(optionsArray));
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(option);
    checkAnswer(option, optionsCorrect);
  };
  return (
    <>
      <h4>{mcqData.m_title}</h4>
      <form onSubmit={handleSubmit}>
        <div className="radio">
          <table>
            <tbody>
              {shuffledArray.map((paragraph, key) => (
                <tr key={key}>
                  <td>
                    <label>
                      <input
                        type="radio"
                        name="selected_option"
                        id="selected_option"
                        value={paragraph}
                        onChange={(e) => setOption(e.target.value)}
                      />
                      {paragraph}
                    </label>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          <button type="submit">Check Answer</button>
        </div>
      </form>
    </>
  );
};
export default QuizTakePage;
function checkAnswer(optionVar, corr) {
  if (optionVar == null) {
    console.log("Select an Answer");
  }
  if (optionVar === corr) {
    console.log("Answer is Correct");
  } else {
    console.log("Wrong Answer");
  }
} 
Sign up to request clarification or add additional context in comments.

2 Comments

It's working fine. But I'm getting this warning Line 14:6: React Hook useEffect has a missing dependency: 'optionsArray'. Either include it or remove the dependency array react-hooks/exhaustive-deps
It's nothing. It wants useEffect to have a dependency. But if you only use in mount, you don't have a dependency. If you use it for some other condition, you can use that as dependency.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.