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

React组件调用API先返回undefined再获数据,求解决方案

解决React useEffect异步获取API数据先返回undefined的问题

问题原因

React组件初始化时,tableData的初始state未设置默认值,默认是undefined。而getData是异步函数,API请求需要时间,所以组件第一次渲染时tableData还是undefined,等请求完成调用setTableData后才会触发重渲染拿到有效数据。这是React异步更新和API请求的正常特性,没法跳过初始渲染直接拿到数据,但可以通过以下方式优化。

解决方案

1. 给tableData设置初始空数组

将tableData的初始state设为空数组,这样初始渲染时DataGrid的rows属性就不会是undefined,避免组件报错或异常显示:

const [tableData, setTableData] = useState([]); // 初始值设为空数组

2. (可选)添加加载状态提升用户体验

在数据请求过程中显示加载提示,让用户知道数据正在获取:

const [loading, setLoading] = useState(false);

const getData = async () => {
  setLoading(true); // 请求开始时开启加载状态
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/users');
    setTableData(response.data);
  } catch (err) {
    console.log(err);
  } finally {
    setLoading(false); // 请求结束(成功/失败)都关闭加载状态
  }
}

渲染时根据loading状态切换显示内容:

return (
  <div className='table'>
    {loading ? (
      <div>加载中...</div> // 可替换为自定义加载组件
    ) : (
      <DataGrid
          rows={tableData}
          columns={columnData.concat(activeColumn)}
          pageSize={pageSize}
          onPageSizeChange={(newPageSize) => setPageSize(newPageSize)}
          rowsPerPageOptions={[5, 10, 25, 50, 100]}
          checkboxSelection
      />
    )}
  </div>
)

3. 调整函数声明避免lint警告

原代码中getData定义在useEffect之后,虽然能运行,但React的ESLint规则可能会提示依赖缺失。可以把getData移到useEffect之前,或者用useCallback包裹:

const getData = useCallback(async () => {
  // 原getData逻辑
}, []); // 依赖为空数组,无需外部变量

useEffect(() => {
  getData();
}, [getData]); // 添加到依赖数组

修改后的完整代码

const Table = () => {
    const [pageSize, setPageSize] = useState(10);  
    const [tableData, setTableData] = useState([]); // 初始空数组
    const [loading, setLoading] = useState(false);

    const getData = async () => {
      setLoading(true);
      try {
        const response = await axios.get('https://jsonplaceholder.typicode.com/users');
        setTableData(response.data);
      } catch (err) {
        console.log(err);
      } finally {
        setLoading(false);
      }
    }

    useEffect(() => {
      getData();
    }, [])
    
    const activeColumn = [
      {field: 'action', headerName: 'Action', width: 200, renderCell:() => {
        return(
          <div className='cellAction'>
            <div className='viewButton'>View</div>            
            <div className='deleteButton'>Delete</div>            
          </div>
        )
      }}
    ]

  return (
    <div className='table'>
      {loading ? (
        <div>加载中...</div>
      ) : (
        <DataGrid
            rows={tableData}
            columns={columnData.concat(activeColumn)}
            pageSize={pageSize}
            onPageSizeChange={(newPageSize) => setPageSize(newPageSize)}
            rowsPerPageOptions={[5, 10, 25, 50, 100]}
            checkboxSelection
        />
      )}
    </div>
  )
}

关键说明

异步API请求本身需要时间,React组件无法在第一次渲染时就直接拿到请求结果。上述方案的核心是处理初始状态和优化用户体验,避免undefined导致的组件异常,同时让用户感知到数据加载过程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:46:05