You need to enable JavaScript to run this app. React设置状态变量无效果:useEffect内更新savedIds后值始终为空
优惠活动
大模型
产品
解决方案
定价
更多

React设置状态变量无效果:useEffect内更新savedIds后值始终为空

问题原因

  1. React 状态更新为异步批量执行逻辑,调用setSavedItems(json)后,当前作用域内的savedItems还是本次渲染初始的空数组,不会立刻变为接口返回的新值,后续执行savedItems.map时遍历的是空数组,因此savedIds会被设置为空。
  2. 你的useEffect依赖数组为空,但内部用到了props.token,如果后续token发生变化,该副作用不会重新执行,存在潜在逻辑问题。

修复方案

可根据实际场景选择以下任意一种修复方式:

方案1:直接用接口返回值生成ids数组

不需要等待savedItems状态更新,拿到接口返回数据后直接生成ids数组同时更新两个状态即可:

.then((json) => {
  if (isMounted) {
    setSavedItems(json)
    // 直接用接口返回的json生成ids,额外加Number转换匹配你要的数字格式
    const idsArray = json.map((item) => Number(item.site_id))
    setSavedIds(idsArray)
  }
})

方案2:拆分副作用,监听savedItems变化自动更新ids

如果你需要savedItems每次变化都自动同步更新savedIds,可以拆分出单独的副作用逻辑:

// 原useEffect仅负责请求数据更新savedItems,补充props.token到依赖数组
useEffect(() => {
  let isMounted = true;
  if (props.token) {
    fetch(url, {
        method: 'GET',
        credentials: 'include',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Token ' + props.token,
        }
      })
      .then((response) => response.json())
      .then((json) => {
        if (isMounted) setSavedItems(json)
      })
      .catch((error) => console.error(error))
      .finally(() => isMounted = false);
  }
}, [props.token]);

// 新增useEffect监听savedItems变化,自动生成savedIds
useEffect(() => {
  const idsArray = savedItems.map((item) => Number(item.site_id))
  setSavedIds(idsArray)
}, [savedItems])

优化建议

如果savedIds完全是派生自savedItems的状态,你甚至可以不用单独将其存为state,每次渲染时直接计算即可,避免多余的状态同步问题:

const [savedItems, setSavedItems] = useState([]);
// 直接计算派生值,savedItems变化时会自动更新
const savedIds = savedItems.map(item => Number(item.site_id))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 17:24:10