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

React组件提前返回未加载状态?异步数据渲染问题求解

解决React组件异步数据渲染问题

问题根源

  1. 普通变量无法触发重渲染:你用let elements = []存储渲染内容,异步请求完成后更新这个变量,但React不会监听普通JS变量的变化,所以组件不会重新渲染,新的内容永远不会显示。
  2. 初始判断逻辑错误:elements初始是数组,if (elements)始终为真,组件一开始就返回空数组的渲染结构,不会进入"Not yet loaded"分支;而异步完成后更新elements也无法触发重渲染,导致数据加载后界面没变化。

修复方案

使用React的useState管理状态,useEffect处理异步请求,让数据变化能触发组件重渲染:

import { AuthContext } from "../../App";
import { useContext, useEffect, useState } from 'react';
import axios from 'axios';

export default function Assignments({ clicked }) {
    const { loggedIn } = useContext(AuthContext);
    // 用useState管理题目数据和加载状态
    const [questions, setQuestions] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        // 定义异步请求函数
        const fetchAssignments = async () => {
            if (!loggedIn) {
                setLoading(false);
                return;
            }
            try {
                setLoading(true);
                const result = await axios.get('http://localhost:2000/database/assignments');
                const qids = result.data["assignments"];
                const result2 = await axios.post('http://localhost:2000/database/questions', {
                    assignments: qids
                }, { headers: {'Content-Type': 'Application/json' } });

                const fetchedQuestions = result2.data["assignments"];
                setQuestions(fetchedQuestions);
            } catch (err) {
                console.log(err);
                setQuestions([]);
            } finally {
                setLoading(false);
            }
        };

        fetchAssignments();
    }, [loggedIn]); // 依赖loggedIn,登录状态变化时重新请求

    // 根据状态渲染不同内容
    if (loading) {
        return <>Not yet loaded</>;
    }

    if (!questions.length) {
        return <>No assignments found</>;
    }

    return (
        <div className="flex flex-col gap-y-4 mt-1.5">
            {questions.map(assignment => (
                <div key={assignment.qid} className="p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-700 dark:border-gray-700">
                    <a href={`/codeground/${assignment.qid}`}>
                        <h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">{assignment.heading}</h5>
                    </a>
                    <p className="mb-3 font-normal text-gray-700 dark:text-gray-400">{assignment.description}</p>
                    <a href={`/codeground/${assignment.qid}`} className="inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
                        Open Assignment
                        <svg className="w-3.5 h-3.5 ml-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
                            <path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M1 5h12m0 0L9 1m4 4L9 9"/>
                        </svg>
                    </a>
                </div>
            ))}
        </div>
    );
}

关键修改点

  • 状态管理:用useState创建questions存储题目数据,loading标记加载状态,这两个状态变化时会自动触发组件重渲染。
  • 异步请求放入useEffect:把异步请求逻辑放到useEffect中,依赖loggedIn,确保登录状态变化时重新拉取数据;同时在请求开始、结束/失败时更新loading状态。
  • 渲染逻辑优化:根据loading状态显示加载提示,根据questions长度判断是否显示空状态,避免初始空数组的误渲染。
  • 修复路由链接:把原来的#改成/codeground/${assignment.qid},符合你的注释需求。

内容的提问来源于stack exchange,提问作者Alpha々 Reaper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:20:35