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

React嵌套函数中第二个函数无法获取useState更新ID的问题

问题原因

你的代码存在两个核心逻辑错误,导致id无法正常被第二个请求读取:

  • fetch是异步非阻塞方法,你发起第一个接口请求后,不会等接口返回、setId执行完成,就会立刻同步执行getCMSPage,此时读取到的id永远是初始值。
  • React的useState更新是异步的,状态更新后需要等组件下一次重渲染,才能在新的作用域中拿到最新值。你在同一次函数执行的闭包里,永远拿不到setId更新后的id值。
  • 额外细节问题:你声明id状态的初始值是带空格的字符串' ',并非你描述的空字符串'',该问题不影响核心报错。

连续两次保存文件时功能正常,是热更新带来的偶发现象:第一次保存触发的请求已经把id写入状态,第二次保存触发热重载时,组件重新执行会读取到上一次缓存的id值,和代码逻辑正确性无关。

修复方案

根据你的业务场景二选一即可:

方案1:链式调用(无多余状态,性能最优)

如果id不需要在组件其他位置复用,完全没必要把id存入state,拿到第一个接口的返回值后直接发起第二个请求即可,减少一次无意义的组件重渲染:

const [loading, setLoading] = useState(true);
const [data, setData] = useState([]);

const fetchCMSContent = () => {
  const baseConfig = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      'sw-access-key': `${API_KEY}`,
    },
  };

  fetch(`${URL}/store-api/category`, baseConfig)
    .then(res => res.json())
    .then(categoryRes => {
      const cmsId = categoryRes.elements[0].cmsPageId;
      return fetch(`${URL}/store-api/cms/${cmsId}`, baseConfig);
    })
    .then(res => res.json())
    .then(cmsRes => {
      setData(cmsRes.sections);
      setLoading(false);
    })
    .catch(err => console.error('请求异常:', err));
};

useEffect(() => {
  fetchCMSContent();
}, []);

方案2:监听id变化触发请求(适合id需要跨逻辑复用的场景)

如果id需要在组件其他逻辑中使用,必须存入state,就拆分请求逻辑,用useEffect监听id的变化,等id更新为有效值后再发起第二个请求:

const [loading, setLoading] = useState(true);
const [data, setData] = useState([]);
const [id, setId] = useState(''); // 修正初始值为真正的空字符串

// 第一个effect仅负责获取id
useEffect(() => {
  const requestConfig = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      'sw-access-key': `${API_KEY}`,
    },
  };
  fetch(`${URL}/store-api/category`, requestConfig)
    .then(res => res.json())
    .then(res => setId(res.elements[0].cmsPageId))
    .catch(err => console.error('分类接口请求失败:' + err));
}, []);

// 监听id变化,id存在时才发起cms页面请求
useEffect(() => {
  if (!id) return;
  const requestConfig = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      'sw-access-key': `${API_KEY}`,
    },
  };
  fetch(`${URL}/store-api/cms/${id}`, requestConfig)
    .then(res => res.json())
    .then(cmsRes => {
      setData(cmsRes.sections);
      setLoading(false);
    })
    .catch(err => console.error('CMS接口请求失败:' + err));
}, [id]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:21:07