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

React中useEffect获取API数据并渲染失败问题求助

问题分析与解决方案

核心问题

你的代码存在两个关键问题,导致selectData始终为null,页面持续显示Loading...:

  1. 异步时序错误:get是异步函数,调用get()后立刻执行data.forEach时,axios请求还未完成,data仍为初始空数组,无法找到id为1的元素。
  2. useEffect依赖缺失:即便后续data通过setData更新,由于第一个useEffect的依赖数组为空,它不会重新执行,也就不会再次遍历data设置selectData。

修复方案(两种可选)

方案一:请求成功后直接处理目标数据

在get函数中拿到返回数据后,同时设置data和selectData,无需等待组件重新渲染:

import React from "react";
import axios from "axios";

export const Teste = () => {
  const [data, setData] = React.useState([]);
  const [selectData, setSelectData] = React.useState(null);

  const get = async () => {
    try {
      const response = await axios.get("http://localhost:5000/posts");
      const posts = response.data;
      setData(posts);
      // 直接定位id为1的帖子并设置
      const targetPost = posts.find(post => post.id === 1);
      if (targetPost) {
        setSelectData(targetPost);
      }
    } catch (err) {
      console.log(err);
    }
  };

  React.useEffect(() => {
    get();
  }, []);

  return (
    <section>
      {selectData !== null ? (
        <div>
          <h1>{selectData.title}</h1>
          <div>
            <p>{selectData.text}</p>
          </div>
          <button>Atualizar</button>
        </div>
      ) : (
        "Loading..."
      )}
    </section>
  );
};

方案二:监听data变化,单独处理selectData

保留原有get函数,新增一个依赖data的useEffect,当data更新时自动查找并设置目标数据:

import React from "react";
import axios from "axios";

export const Teste = () => {
  const [data, setData] = React.useState([]);
  const [selectData, setSelectData] = React.useState(null);

  const get = async () => {
    await axios
      .get("http://localhost:5000/posts")
      .then((response) => setData(response.data))
      .catch((err) => console.log(err));
  };

  React.useEffect(() => {
    get();
  }, []);

  // 当data更新时,自动查找并设置目标数据
  React.useEffect(() => {
    if (data.length > 0) {
      const targetPost = data.find(post => post.id === 1);
      if (targetPost) {
        setSelectData(targetPost);
      }
    }
  }, [data]);

  return (
    <section>
      {selectData !== null ? (
        <div>
          <h1>{selectData.title}</h1>
          <div>
            <p>{selectData.text}</p>
          </div>
          <button>Atualizar</button>
        </div>
      ) : (
        "Loading..."
      )}
    </section>
  );
};

额外优化提示

  • 用find替代forEach更高效,find找到目标元素后会直接返回,无需遍历整个数组。
  • 异步函数中尽量统一使用try/catch或.catch写法,避免混合使用(方案一的try/catch比原代码的await + .then/.catch更清晰)。

内容的提问来源于stack exchange,提问作者Lucas Santana Figueiredo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:35:21