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

React中useEffect内useState数组未更新的问题求助

问题描述

我在React应用中运行以下代码,尝试从后端获取数据并通过ReactTabulator渲染表格:

import { useState, useEffect } from "react";
import 'react-tabulator/lib/styles.css';
import { ReactTabulator } from 'react-tabulator'

export default function Project() {
    const [projects, setProjects] = useState([]);

    
    const [isLoading, setLoading] = useState(true);
    const projectListUri = '/api/projects';
    // const apiPath = process.env.REACT_SERVER_HOST + projectListUri;
    useEffect(() => {
        fetch("http://localhost:8000/api/projects")
            .then((response) => response.json())
            .then((data) => {
                console.log(data); // line 16
                setProjects(data);
                console.log(projects); //line 18
                setLoading(false);
            }).catch((error) => {
                console.log(error.message);
                setLoading(false);
            });
    }, []);

    return (
        <div>
            {isLoading ? (
                <p>Loading...</p>
            ) : (
                <ReactTabulator
                    data={projects}
                    autoColumns={true}
                    layout={"fitColumns"}
                />
            )}
        </div>
    );
}

遇到的问题:

  • 请求过程正常,第16行能正确打印后端返回的数据
  • 第18行始终输出空数组
  • ReactTabulator抛出错误:Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'slice')
  • isLoading状态能正常更新,尝试过setProjects(...data); setProjects([data]); setProjects(...projects, ...data);这些写法均无效
解决方案

1. 第18行打印空数组的原因

这是React状态更新的正常特性:setProjects是异步操作,调用后不会立刻更新projects变量,所以你在调用setProjects后马上打印projects,得到的还是更新前的初始空数组。这个现象不影响状态的最终更新,无需纠结。

2. 解决ReactTabulator报错的核心操作

ReactTabulator要求data属性必须是数组类型,报错说明你传入的projects不是数组——大概率是后端返回的数据结构不是直接的数组,而是包含数组的对象(比如{ data: [项目列表] }这种格式)。

具体步骤:

  • 打开浏览器控制台,查看第16行console.log(data)的输出结构:
    • 如果输出是类似{ projects: [...] }的对象,提取里面的数组部分再设置状态:
      setProjects(data.projects); // 替换原来的setProjects(data)
      
    • 如果后端返回的是单个项目对象而非数组,把它包装成数组:
      setProjects([data]);
      

3. 额外优化:增加数据格式校验

为避免后续因数据格式问题报错,可以在设置状态前先校验数据类型:

.then((data) => {
    console.log(data);
    // 确保最终传入ReactTabulator的是数组
    const validData = Array.isArray(data) ? data : [data];
    setProjects(validData);
    setLoading(false);
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:30:22