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

React中调用HTTP GET请求获取数据构建表格的问题求解

问题根因

React 中setState类的状态更新方法是异步批处理的,你在调用setServerData(response.data)后,当前代码块中的serverData依旧是初始的空数组,状态更新会等到当前同步代码执行完后才生效,因此紧接着调用fillRows()时遍历的是空数组,最终得到的rows自然也是空的。

解决方案

提供两种常用的修复方式:

方案1:直接将接口返回数据传入处理函数

无需等待状态更新,直接把接口拿到的响应数据作为参数传给fillRows,避免依赖还没更新的state:

import React, { useEffect, useState } from "react";
import axios from "axios";
import { DataGrid } from "@material-ui/data-grid";

function ServersTable() {
  const [loadingData, setLoadingData] = useState(true);
  const [serverData, setServerData] = useState([]);
  const [rows, setRows] = useState([]);
  const columns = [
    { field: "hostname", headerName: "Hostname", width: 70 },
    { field: "memory", headerName: "Memória", width: 70 },
    { field: "vCpus", headerName: "vCPUs", width: 70 },
    { field: "disk", headerName: "Disco", width: 70 },
    { field: "ip", headerName: "IP", width: 70 },
  ];

  useEffect(() => {
    async function getData() {
      await axios
        .get("http://localhost:3333/servers")
        .then((response) => {
          const data = response.data
          setServerData(data);
          // 直接把拿到的新数据传给处理函数
          fillRows(data);
          setLoadingData(false);
        })
    }
    if (loadingData) {
      getData();
    }
  }, []);

  // 接收传入的数据源做处理,不依赖state
  function fillRows(data) {
    let rowArray = [];
    for (let count = 0; count < data.length; count++) {
      let row;
      row = {
        id: count,
        hostname: data[count].hostname,
        memory: data[count].configuracao.memoryProvisioned + " GB",
        vCpus: data[count].configuracao.cpuProvisioned + " vCPUs",
        disk: data[count].configuracao.totalDiskGB + " GB",
        ip: data[count].ip,
      };
      rowArray.push(row);
    }
    setRows(rowArray);
  }

  return (
    <>
      {loadingData ? (
        <p>Loading Please Wait...</p>
      ) : (
        <DataGrid rows={rows} columns={columns} checkboxSelection />
      )}
    </>
  );
}

export default ServersTable;

方案2:通过useEffect监听serverData变化触发处理

如果需要依赖serverData状态做后续处理,可以新增一个副作用监听serverData的变化,等它更新后再执行rows的生成逻辑:

// 只需要修改两处,其余代码不变
useEffect(() => {
  async function getData() {
    await axios
      .get("http://localhost:3333/servers")
      .then((response) => {
        setServerData(response.data);
        setLoadingData(false);
        // 删掉原来的fillRows调用
      })
  }
  if (loadingData) {
    getData();
  }
}, []);

// 新增这个useEffect,监听serverData变化
useEffect(() => {
  fillRows()
}, [serverData])
优化建议

rows属于可以通过serverData计算得到的派生状态,不需要单独维护state,可以用useMemo减少冗余状态:

const rows = useMemo(() => {
  return serverData.map((item, index) => ({
    id: index,
    hostname: item.hostname,
    memory: item.configuracao.memoryProvisioned + " GB",
    vCpus: item.configuracao.cpuProvisioned + " vCPUs",
    disk: item.configuracao.totalDiskGB + " GB",
    ip: item.ip,
  }))
}, [serverData])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:24:04