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

React使用axios获取数据时访问questionText报undefined错误

问题根源

报错和接口返回的JSON结构无关,是代码里的React执行逻辑错误:

  • 普通局部变量修改不会触发组件重渲染:你初始化questions为空数组,组件首次渲染时会直接执行到questions[currentQuestion].questionText这行,此时questions[0]是undefined,读取undefined的属性直接抛出Cannot read properties of undefined错误。静态注释数据之所以正常,是因为变量初始化时就带了完整题目内容,首次渲染就能读到对应值。
  • 接口请求直接写在组件函数体中,每次组件重渲染都会重复发起请求,就算后续改用变量存值也会导致无限重渲染、请求死循环。
  • 之前改用类组件state仍复现错误,核心是没做加载态兜底:接口请求是异步的,首次渲染时state里的题目数组还是空的,没等数据返回就去读数组项的属性,一样会抛错。
修复方案

按以下步骤改代码即可:

  1. 引入副作用钩子,将题目数据改为响应式state
    把react的引入行改成:
    import { useState, useEffect } from "react";
    
    替换原来的var questions = []为state定义:
    const [questions, setQuestions] = useState([]);
    const [currentQuestion, setCurrentQuestion] = useState(0);
    const [popup, setPopup] = useState(false);
    
  2. 把接口请求移到useEffect中,仅在组件首次挂载时执行,拿到数据后通过state方法更新,触发组件重渲染:
    useEffect(() => {
      axios.get('http://localhost/getQuestions.php',{withCredentials: true})
      .then(res => {
        // 若接口返回结构是带code/msg的包裹层,此处取对应层级即可,比如res.data.data
        setQuestions(res.data);
      })
    }, []);
    
    删掉原来直接写在函数体里的getData()调用和普通的getData函数定义。
  3. 增加加载态兜底,在题目数据没加载完成时不渲染题目区域,从根源避免空值读取错误:
    把return中原来的.main-quiz区块替换为如下逻辑:
    <div className="main-quiz">
      {questions.length === 0 ? (
        <div className="loading">题目加载中,请稍候...</div>
      ) : (
        <>
          <div className="progressbar" ></div>
          <div className="question">{questions[currentQuestion].questionText}</div>
          <div className="answers">
            {questions[currentQuestion].answerOptions.map((answerOption, idx) =>(
              <button key={idx} onClick={() => handleButtonClick(answerOption.isCorrect)}>
                <div className="choice">{answerOption.answerText}</div>
              </button>
            ))}
          </div>
        </>
      )}
    </div>
    
    这里顺便修复两个原有逻辑bug:
    • 列表遍历增加key属性,消除React渲染警告
    • 原代码的onClick={handleButtonClick}没有传入当前选项的isCorrect参数,判分逻辑永远拿不到正确值,改为箭头函数包裹传参
  4. 校验接口返回层级:如果按上述修改后加载完成仍报错,直接在axios的then回调里打印res.data,确认是否拿到的是直接的题目数组。部分PHP接口会返回带状态码的包裹结构(比如{code:200, data: [题目数组]}),这种情况需要取res.data.data传给setQuestions。

内容的提问来源于stack exchange,提问作者Turgut Güvercin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:54:15