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

React中useEffect调用两个方法仅显示第二个结果的问题求解

状态更新被覆盖的问题解决

问题描述

在useEffect中调用两个数据获取方法时,第二个方法的执行会覆盖第一个的结果,仅能看到第二个方法的输出,第一个的结果短暂显示后消失。

两种写法均出现相同问题:

  1. 单个useEffect内调用两个方法:
useEffect(() => {
  getPages();
  getFeatures();
}, []);

此时仅保留getFeatures()的结果,getPages()的结果一秒后消失。

  1. 两个独立useEffect分别调用:
useEffect(() => {
  getFeatures();
  console.log("featFeatures");
}, []);
useEffect(() => {
  getPages();
  console.log("getPages");
}, []);

能看到两个控制台日志,但仍只保留第二个useEffect的结果,第一个的结果被覆盖。

相关方法代码:
getPages():

const getPages = async () => {
  await getAllPagesFromUser(pageSkip, pageLimit, token).then((data) => {
    if (data.error) {
      console.log(data.error);
    } else {
      setValues({ ...values, pages: data });
    }
  });
};

getFeatures():

const getFeatures = () => {
  getAllFeaturesFromUser(featureSkip, featureLimit, token).then((data) => {
    if (data.error) {
      console.log(data.error);
    } else {
      setValues({ ...values, features: data });
    }
  });
};

原因分析

核心问题是状态更新的闭包陷阱:
两个方法中的values都是组件初始渲染时的快照,当第一个方法完成异步请求并更新状态后,第二个方法执行时依然使用旧的values对象展开,导致第一个方法更新的pages字段被覆盖,最终状态仅保留第二个方法设置的features字段。

解决方案

方案1:使用函数式更新(推荐)

React状态更新函数支持传入回调,回调参数为当前最新状态值,确保每次更新都基于最新状态:

修改getPages():

const getPages = async () => {
  const data = await getAllPagesFromUser(pageSkip, pageLimit, token);
  if (data.error) {
    console.log(data.error);
  } else {
    setValues(prevValues => ({ ...prevValues, pages: data }));
  }
};

修改getFeatures():

const getFeatures = async () => {
  const data = await getAllFeaturesFromUser(featureSkip, featureLimit, token);
  if (data.error) {
    console.log(data.error);
  } else {
    setValues(prevValues => ({ ...prevValues, features: data }));
  }
};

方案2:合并请求后一次性更新

若两个请求互相独立,可通过Promise.all并行发起请求,待所有请求完成后一次性更新状态,避免多次更新冲突:

useEffect(() => {
  const fetchData = async () => {
    try {
      const [pagesData, featuresData] = await Promise.all([
        getAllPagesFromUser(pageSkip, pageLimit, token),
        getAllFeaturesFromUser(featureSkip, featureLimit, token)
      ]);
      
      const newValues = { ...values };
      if (!pagesData.error) newValues.pages = pagesData;
      if (!featuresData.error) newValues.features = featuresData;
      
      setValues(newValues);
    } catch (err) {
      console.error('请求出错:', err);
    }
  };
  
  fetchData();
}, []);

这种方式仅进行一次状态更新,既避免覆盖问题,又能提升请求效率。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:45:39