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

React中如何用setState处理存在依赖关系的两个GET请求?

处理依赖式请求的最优方案

你遇到的核心问题是依赖异步状态更新的请求时机错误:useState的更新是异步批量处理的,第一个请求里调用setPageId后,state不会立刻更新,所以后续调用getTemplates时拿到的还是初始的null。下面是两种最可靠的解决思路:


方案一:直接传递pageId,绕过state异步更新(推荐)

既然第一个请求已经拿到了pageId,直接把这个值作为参数传给getTemplates,完全避开state的异步问题,这是最直接高效的方式。

修改后的代码:

const [loadedSharePages, setLoadedSharePages] = useState(null);
const [loadedTemplates, setLoadedTemplates] = useState([]);
// 若其他业务逻辑不需要用到pageId,这个state甚至可以删掉
const [pageId, setPageId] = useState(null);

const url = useParams().url;

const getCustomUrl = async () => {
  try {
    const res = await axios({
      method: "GET",
      url: `http://localhost:8080/api/pages/DT/${url}`,
      headers: {
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    });
    console.log("Respond from the request getCusomUrl-->", res);
    setLoadedSharePages(res.data.page);
    setPageId(res.data.page.id);
    // 直接把请求返回的pageId传给getTemplates,不用等state更新
    await getTemplates(res.data.page.id);
  } catch (err) {
    console.log(err);
  }
};

// 修改getTemplates,接受pageId参数
const getTemplates = async (targetPageId) => {
  try {
    const res = await axios({
      method: "GET",
      url: `http://localhost:8080/api/RE/template/${targetPageId}`,
      headers: {
        "Content-Type": "multipart/form-data",
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    });
    console.log("Respond from the request -->", res);
    setLoadedTemplates(res.data.templates);
    console.log("Res.data.templates -->", res.data.templates);
  } catch (err) {
    console.log(err);
  }
};

useEffect(() => {
  getCustomUrl();
}, [url]); // 依赖url参数,当url变化时重新发起请求

方案二:用useEffect监听pageId变化(适合依赖state的场景)

如果你的业务逻辑确实需要把pageId存在state中(比如其他组件或逻辑要用到),可以用useEffect监听pageId的变化,当它不为null时再发起第二个请求。

修改后的代码:

const [loadedSharePages, setLoadedSharePages] = useState(null);
const [loadedTemplates, setLoadedTemplates] = useState([]);
const [pageId, setPageId] = useState(null);

const url = useParams().url;

const getCustomUrl = async () => {
  try {
    const res = await axios({
      method: "GET",
      url: `http://localhost:8080/api/pages/DT/${url}`,
      headers: {
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    });
    setLoadedSharePages(res.data.page);
    setPageId(res.data.page.id);
  } catch (err) {
    console.log(err);
  }
};

const getTemplates = async () => {
  // 先判断pageId是否有效,避免发起无效请求
  if (!pageId) return;
  try {
    const res = await axios({
      method: "GET",
      url: `http://localhost:8080/api/RE/template/${pageId}`,
      headers: {
        "Content-Type": "multipart/form-data",
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    });
    setLoadedTemplates(res.data.templates);
  } catch (err) {
    console.log(err);
  }
};

// 第一个副作用:发起页面信息请求
useEffect(() => {
  getCustomUrl();
}, [url]);

// 第二个副作用:监听pageId变化,发起模板请求
useEffect(() => {
  getTemplates();
}, [pageId]); // pageId更新时触发

为什么你之前的方法没生效?

  • Promise链式调用:getCustomUrl()执行完成后,setPageId的异步更新还未完成,此时pageId依然是null,所以getTemplates()拿到的还是旧值。
  • setTimeout:完全不可靠,请求耗时不确定,无法保证在指定时间内state完成更新。
  • useEffect加pageId依赖无效:大概率是没处理pageId为null的情况,导致第一次触发时发起了无效请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:30:59