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

React JS调用多对象API报错:无法读取undefined的question属性

问题解决思路

核心问题原因

  1. 初始状态与API返回结构不匹配:你把初始状态设为[""],这是一个包含空字符串的数组,但OpenTDB返回的是题目对象数组。初始渲染时数组里的元素是字符串而非对象,且此时数组长度仅为1,访问quiz[1]时该位置本身不存在,直接读取.question自然触发报错。
  2. 异步请求未完成时的提前访问:API请求是异步执行的,组件第一次渲染时quiz还是初始值,此时quiz[1]为undefined,直接读取属性就会抛出TypeError。

解决方案

1. 修正初始状态

把初始状态改为空数组,和API返回的数据结构保持一致,避免初始阶段的类型不匹配问题:

const [quiz, setQuiz] = useState([]);

2. 渲染时增加安全检查

提供三种可行的安全访问方式,按需选择:

  • 可选链操作符(最简洁):用?.判断元素是否存在,不存在时返回undefined,不会触发报错:
    <p>第二题:{quiz[1]?.question}</p>
    
  • 条件渲染:先判断数组长度是否足够,再渲染对应内容:
    {quiz.length >= 2 && <p>第二题:{quiz[1].question}</p>}
    
  • 遍历数组(推荐,适配任意题目数量):用map遍历数组,自动跳过不存在的元素,从根源避免越界访问:
    <div>
      {quiz.map((question, idx) => (
        <div key={idx}>
          <h4>第{idx + 1}题</h4>
          <p>{question.question}</p>
        </div>
      ))}
    </div>
    

完整示例代码

import { useState, useEffect } from 'react';

function Quiz() {
  // 初始状态设为空数组
  const [quiz, setQuiz] = useState([]);

  useEffect(() => {
    async function fetchQuestions() {
      try {
        const res = await fetch('https://opentdb.com/api.php?amount=5');
        const data = await res.json();
        setQuiz(data.results);
      } catch (err) {
        console.error('获取题目失败:', err);
      }
    }

    fetchQuestions();
  }, []);

  return (
    <div className="quiz-container">
      {/* 遍历渲染所有题目 */}
      {quiz.map((item, index) => (
        <div key={index} className="question-card">
          <h3>题目 {index + 1}</h3>
          <p>{item.question}</p>
        </div>
      ))}

      {/* 单独访问第二题的安全写法 */}
      {quiz.length >= 2 && (
        <div className="single-question">
          <h3>第二题单独展示</h3>
          <p>{quiz[1].question}</p>
        </div>
      )}
    </div>
  );
}

export default Quiz;

内容的提问来源于stack exchange,提问作者Mohamed Amine Hachemi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:15:38