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

React TypeScript中useEffect赋值后statResult仍为空的问题

问题分析与解决方案

核心问题

  1. 初始状态类型不匹配:statResult初始值设为字符串"",但接口返回的是对象类型。状态类型不匹配会导致更新逻辑出现异常,即使调用setStatResult,也可能在渲染阶段表现为空。
  2. useEffect依赖缺失:useEffect的依赖数组为空,未包含Props.name。若父组件传递的Props.name发生变化,组件不会重新发起请求,statResult始终是旧数据或初始值。
  3. 无错误处理逻辑:fetch请求未添加错误捕获,一旦请求失败(如接口地址错误、网络问题),statResultJson会是undefined,但代码仍会设置isLoading为false,此时渲染时statResult还是初始空字符串,无法读取name、win等属性。

修复后的代码

import { StatPanelProps } from "./StatPanelprops";
import { useState, useEffect } from "react"

// 定义明确的接口类型替代any,提升类型安全性
interface StatResult {
  name: string;
  win: number;
  loss: number;
}

export function StatPanel(Props: StatPanelProps) {
    // 初始值设为null,匹配接口返回的对象类型
    const [statResult, setStatResult] = useState<StatResult | null>(null)
    const [isLoading, setIsLoading] = useState(true)
    const [error, setError] = useState<string | null>(null)

    useEffect(() => {
        async function load() {
            try {
                setIsLoading(true);
                setError(null);
                const statResponse = await fetch(`http://localhost:3000/stats/${Props.name}`);
                // 检查请求是否成功
                if (!statResponse.ok) {
                    throw new Error(`请求失败: ${statResponse.status}`);
                }
                const statResultJson = await statResponse.json();
                setStatResult(statResultJson);
            } catch (err) {
                setError(err instanceof Error ? err.message : "未知错误");
            } finally {
                setIsLoading(false);
            }
        }
        load()
    }, [Props.name]) // 添加Props.name到依赖数组,确保参数变化时重新请求

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

    if (error) {
        return <div>加载失败: {error}</div>
    }

    // 确保statResult不为null时再渲染,避免属性读取报错
    if (!statResult) {
        return <div>无数据</div>
    }

    return (
        <ul>
            <li id={(Props.id + 1).toString()}>Név: {statResult.name}</li>
            <li id={(Props.id + 2).toString()}>Nyert: {statResult.win}</li>
            <li id={(Props.id + 3).toString()}>Vesztett: {statResult.loss}</li>
            <li id={(Props.id + 4).toString()}>Arány: {(statResult.win / (statResult.win + statResult.loss)) * 100}</li>
        </ul>
    )
}

关键修复点

  • 类型修正:将statResult初始值改为null,定义StatResult接口替代any,既匹配接口返回的对象类型,也强化了TypeScript的类型校验能力。
  • 依赖补全:在useEffect依赖数组中加入Props.name,保证参数变化时组件能重新发起请求获取最新数据。
  • 错误处理:添加try/catch捕获请求异常,在finally中统一设置isLoading为false,避免请求失败后组件一直处于加载状态,同时给用户展示错误信息。
  • 渲染安全校验:渲染数据前先检查statResult是否存在,避免读取null的属性导致页面报错。

内容的提问来源于stack exchange,提问作者Gábor WIttmann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 20:12:34