简体   繁体   中英

React throwing an undefined error but only in my JSX

What I want is to display the amount of answers you got right on the trivia at the end of the 10 question quiz. I have everything working up to this point. I expect it to display the number of correct answers, but instead I get an error "cannot read property of undefined" pointing to this line

<p> {results.correct} </p>

Here's the whole component, I hope I labeled everything well enough to make it readable

function App() {
  //useState variables
  const [results, setResults] = useState({
    correct: 0,
    answer: "True",
  });
  const [arrayIndex, setArrayIndex] = useState(0);
  const [classOn, setClassOn] = useState("trivia-cards-initial");
  const [triviaArray, setTriviaArray] = useState([]);
  const [disable, setDisable] = useState(true);

  //useEffects
  useEffect(() => {
    axios
      .get("https://opentdb.com/api.php?amount=10&difficulty=hard&type=boolean")
      .then((res) => {
        setTriviaArray(res.data.results);
      });
  }, []);

  //onclicks and helper functions
  const nextQuestionOnClick = () => {
    setClassOn(`trivia-cards-initial-${arrayIndex}`);
    // setTriviaArray(triviaArray);
    setResults(() => {
      if (triviaArray[arrayIndex].correct_answer === results.answer) {
        setResults({ ...results, correct: results.correct + 1 });
      } else {
        setResults({ ...results });
      }
    });
    setArrayIndex(() => {
      if (arrayIndex > 8) {
        return 9;
      } else {
        return arrayIndex + 1;
      }
    });
    console.log(triviaArray);
    console.log({ ...results });
  };
  const beginOnClick = () => {
    setClassOn(`trivia-cards-initial-${arrayIndex}`);
    // setTriviaArray(triviaArray);
    setArrayIndex(() => {
      if (arrayIndex > 8) {
        return 9;
      } else if (arrayIndex === 0) {
        return arrayIndex;
      } else {
        return arrayIndex + 1;
      }
    });
  };

  const answerButtonTrue = () => {
    setResults({
      ...results,
      answer: "True",
    });
    setDisable(false);
  };
  const answerButtonFalse = () => {
    setResults({
      ...results,
      answer: "False",
    });
    setDisable(false);
  };

  function calculator() {
    return results.correct;
  }

  //JSX
  if (classOn === "trivia-cards-initial") {
    return (
      <div className={classOn}>
        <h1 className="title">Welcome To The Trivia Challange!</h1>
        <h3 className="text-content-middle">
          You will be presented with 10 True or False questions.
        </h3>
        <h3 className="text-content-bottom">Can you score 100%?</h3>
        <div className="begin-btn-bg">
          <button className="buttons" onClick={beginOnClick}>
            BEGIN
          </button>
        </div>
      </div>
    );
  } else if (classOn === "trivia-cards-initial-9") {
    return (
      <div>
        <p> {results.correct} </p>
      </div>
    );
  } else {
    return (
      <div className="bg-cards">
        <div className="trivia-cards">
          <div className={classOn}>
            <h2 className="category">{triviaArray[arrayIndex].category}</h2>
            <h3 className="trivia-questions">{`${triviaArray[arrayIndex].question}`}</h3>
            <button className="true-btn" onClick={answerButtonTrue}>
              True
            </button>
            <button className="true-btn" onClick={answerButtonFalse}>
              False
            </button>
            <p>Correct Answer:{triviaArray[arrayIndex].correct_answer}</p>

            <button
              className="buttons"
              onClick={nextQuestionOnClick}
              disabled={disable}
            >
              Next Question
            </button>
          </div>
        </div>
      </div>
    );
  }
}

Most likely it's due to uninitialised variables and you have to handle it properly. Please use something like this:

{results && typeof results.correct !== "undefined" && (
  <p> {results.correct} </p>
)}

Here you're checking if results and results.correct are truthy, before trying to display it. This should fix it. Let me know.

Or in simple way, you can do:

{results && results.correct > -1 && (
  <p> {results.correct} </p>
)}

The above one is because, what if results.correct is 0 !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM