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

React异步Fetch数据后无法显示问题求助

问题解决思路

你的核心问题有两个:questions是普通数组而非React状态变量,修改它不会触发组件重新渲染;另外还有几个未定义的变量/函数需要补充实现。

1. 将questions改为React状态

React只有状态变量更新时才会重新渲染组件,你用普通数组questions存储数据,就算异步获取到数据并push进去,组件也不会感知到变化,自然不会更新渲染内容。

把const questions = [];改成状态变量:

const [questions, setQuestions] = useState([]);

然后在deneme函数里,不要直接push,而是通过setQuestions更新状态:

const deneme = async () => {
    const querySnapshot = await getDocs(collection(db, selection));
    // 把查询到的文档数据转换成数组
    const fetchedQuestions = querySnapshot.docs.map(doc => doc.data());
    setQuestions(fetchedQuestions);
    setLoading(false);
}

2. 补充未定义的变量与函数

代码里currentQuestion、chooseOption、nextQuestion、finishQuiz都没定义,这会导致渲染时逻辑失效,甚至报错,需要补充这些内容:

  • 增加currentQuestion状态变量,控制当前显示的题目索引:
const [currentQuestion, setCurrentQuestion] = useState(0);
  • 实现chooseOption函数,处理选项选择逻辑(示例逻辑,可根据需求调整):
const chooseOption = (optionKey) => {
    // 这里可以添加判断选项是否正确、更新分数等逻辑
    // 比如:if(questions[currentQuestion].correct === optionKey) setScore(prev => prev + 1);
}
  • 实现nextQuestion函数,切换到下一题:
const nextQuestion = () => {
    setCurrentQuestion(prev => prev + 1);
}
  • 实现finishQuiz函数,处理测验结束逻辑:
const finishQuiz = () => {
    // 比如切换游戏状态、跳转到结果页等
    setGameState("result");
}

3. 修复渲染时的边界判断

虽然用了可选链?.避免了报错,但最好加上边界判断,防止currentQuestion超出数组范围:

比如在加载完成后判断数组是否为空:

if (isLoading) {
    return <div> Loading</div>
}

if (questions.length === 0) {
    return <div>暂无题目数据</div>
}

完整修正后的代码

import { useState, useContext, useEffect } from "react";
import { GameStateContext } from "../helpers/Context"
import { db } from '../../firebase-config'
import { collection, getDocs } from "firebase/firestore";

const Quiz = () => {
 const { score, setScore, gameState, setGameState, selection } = useContext(GameStateContext);
 const [isLoading, setLoading] = useState(true);
 // 改为状态变量
 const [questions, setQuestions] = useState([]);
 // 添加当前题目索引状态
 const [currentQuestion, setCurrentQuestion] = useState(0);

useEffect(() => {
    deneme();
}, [selection]); // 依赖添加selection,当选择的集合变化时重新获取数据

const deneme = async () => {
    setLoading(true); // 重新获取时显示加载
    const querySnapshot = await getDocs(collection(db, selection));
    const fetchedQuestions = querySnapshot.docs.map(doc => doc.data());
    setQuestions(fetchedQuestions);
    setCurrentQuestion(0); // 重置当前题目索引
    setLoading(false);
}

// 实现选项选择函数
const chooseOption = (optionKey) => {
    // 示例:判断选项是否正确并更新分数
    if (questions[currentQuestion]?.correct === optionKey) {
        setScore(prev => prev + 1);
    }
}

// 实现下一题函数
const nextQuestion = () => {
    if (currentQuestion < questions.length - 1) {
        setCurrentQuestion(prev => prev + 1);
    }
}

// 实现结束测验函数
const finishQuiz = () => {
    setGameState("result");
}

if (isLoading) {
    return <div> Loading</div>
}

if (questions.length === 0) {
    return <div>暂无题目数据</div>
}

return (
    <div className="Quiz">
        <h1>{questions[currentQuestion].question}</h1>
        <div className="questions">
            <button
                onClick={() => chooseOption("optionA")}
            >
                {questions[currentQuestion].optionA}
            </button>
            <button
                onClick={() => chooseOption("optionB")}
            >
                {questions[currentQuestion].optionB}
            </button>
            <button
                onClick={() => chooseOption("optionC")}
            >
                {questions[currentQuestion].optionC}
            </button>
            <button
                onClick={() => chooseOption("optionD")}
            >
                {questions[currentQuestion].optionD}
            </button>
        </div>

        {currentQuestion === questions.length - 1 ? (
            <button onClick={finishQuiz} id="nextQuestion">
                Finish Quiz
            </button>
        ) : (
            <button onClick={nextQuestion} id="nextQuestion">
                Next Question
            </button>
        )}

    </div>
)
}

export default Quiz;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:24:10