You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React答题应用报错:TypeError: Cannot read property 'map' of undefined

排查Counter组件中TypeError: Cannot read property 'map' of undefined的问题

Hey there, let's break down why your Counter component is throwing that error and fix up the other messy bits blocking your quiz app from working right.

1. 直接触发错误的核心原因

Let's start with the obvious bug: your Counter component tries to run .map() on this.props.question, but look at how you're passing props to it in the App component:

<Counter questions={this.state.question} />

Two critical issues here:

  • You named the prop questions (plural) but reference it as question (singular) in Counter.
  • this.state.question in your App is initialized as an empty string "" — it's never an array, so trying to call .map() on a string/undefined will always throw that TypeError.

You should be passing the full array of quiz questions from your API (this.state.results) instead of a single empty string.

2. Step-by-Step Fixes

第一步:修正Counter组件的props传递与使用

First, fix the prop in your App's render method:

// Replace the old Counter call in App's render
<Counter questions={this.state.results} />

Then update the Counter component to use the correct plural prop and fix the unanswered question calculation:

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { right: 0, counter: 0 };
  }

  questionAnswered(isRight) {
    this.setState(({ counter, right }) => ({
      counter: counter + 1,
      right: right + (isRight ? 1 : 0) // Ensure we only add 1 for correct answers
    }));
  }

  render() {
    const { questions } = this.props; // Use plural prop name
    const { counter, right } = this.state;
    const unanswered = questions.length - counter; // Calculate using total questions count

    if (unanswered <= 0) {
      return <div>All questions answered! You got {right}/{questions.length} correct.</div>;
    }

    return (
      <div>
        <p>You have {unanswered} questions left, {right} are already correct!</p>
        {questions.map(it => (
          <TheAnswers
            key={it.question}
            {...it}
            hasAnswered={(isRight) => this.questionAnswered(isRight)}
          />
        ))}
        <p>Questions answered: {counter}</p>
      </div>
    );
  }
}

第二步:修复App组件的状态管理

Your App component has several state-related bugs that break functionality:

  • You didn't initialize score in state, so clicking answers will throw an error when trying to do score + 1. Add it to your constructor:
this.state = {
  results: [],
  score: 0,
  currentQuestionIndex: 0 // Add this to track which question the user is on
};
  • Your populateAppWithData method logs a Promise instead of the actual API data. Fix the logging:
populateAppWithData() {
  fetch(API)
    .then(response => response.json())
    .then(data => {
      this.setState({ results: data.results });
      console.log(data.results); // Log the actual questions array
    });
}
  • Remove the broken handleClick method — your TheAnswers component already handles answer clicks, so this redundant method is corrupting your state.

第三步:完善TheAnswers组件的功能

  • Add random sorting for answers (you had the array setup, just missing the sort):
// In TheAnswers' render method
const allAnswers = [...incorrect_answers, correct_answer].sort(() => Math.random() - 0.5);
  • Fix the answerClicked handler to properly pass the boolean to the parent component:
answerClicked = (answer) => () => {
  if (this.state.answered) return;
  const isRight = this.props.correct_answer === answer;
  this.setState({ answered: answer, isRight });
  this.props.hasAnswered(isRight);
};

第四步:Clean up the overall quiz flow

Instead of randomly picking a question each render, use the currentQuestionIndex state to guide the user through questions one by one, and show the final score when done:

// In App's render method
const { results, score, currentQuestionIndex } = this.state;
const currentQuestion = results[currentQuestionIndex];

return (
  <div className="App">
    <h1>Quiz App</h1>
    {currentQuestion ? (
      <TheAnswers
        {...currentQuestion}
        hasAnswered={(isRight) => {
          this.setState(prev => ({
            score: prev.score + (isRight ? 1 : 0),
            currentQuestionIndex: prev.currentQuestionIndex + 1
          }));
        }}
      />
    ) : results.length === 0 ? (
      <p>Loading questions...</p>
    ) : (
      <Counter score={score} totalQuestions={results.length} />
    )}
  </div>
);

3. Final Notes

The root of your error was a simple prop mismatch, but fixing it required untangling some overlapping state management between components. By giving each component a clear job:

  • App: Fetch data, track overall score and current question
  • TheAnswers: Display a single question, handle answer clicks, show feedback
  • Counter: Show final quiz statistics

Your app will work as intended, with no more map errors.

内容的提问来源于stack exchange,提问作者Vicky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:49:58