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

React点击Switch后State未更新,请求传旧值问题求助

问题原因与解决办法

1. 为什么状态不立刻更新、服务器收到旧值?

React的useState更新是异步批量处理的,你调用setRelay1((prev) => !prev)后,relay1变量不会马上变成新值。所以你在setRelay1之后立刻打印relay1、或者用它发请求,拿到的都是更新前的旧状态,这就是服务器收到的总是false的原因。

2. 怎么解决?

方案一:提前计算新状态,直接用新值发请求

既然要反转状态,先算出新值,同时用来更新状态和发请求:

const handleControlRelay1 = () => {
  const newRelayState = !relay1;
  setRelay1(newRelayState);
  axios.put(`http://localhost:4000/relays/1`, {
    id: 2,
    name: "Superman",
    state_1: newRelayState, // 这里用计算好的新值
    state_2: false,
    state_3: false,
    type: "switch-1",
  })
  .then(res => console.log(res.data.message))
  .catch(err => console.log(err.message));
};

方案二:监听状态变化,更新后再发请求

把请求逻辑放到useEffect里,只在relay1变化时执行,点击Switch只负责更新状态:

const handleControlRelay1 = () => {
  setRelay1(prev => !prev);
};

// 监听relay1的变化,状态更新后自动发请求
useEffect(() => {
  // 跳过初始的null状态
  if (relay1 === null) return;
  
  axios.put(`http://localhost:4000/relays/1`, {
    id: 2,
    name: "Superman",
    state_1: relay1,
    state_2: false,
    state_3: false,
    type: "switch-1",
  })
  .then(res => console.log(res.data.message))
  .catch(err => console.log(err.message));
}, [relay1]);

额外提醒

你给relay1初始值设的是null,Switch的checked用!!relay1转成布尔值没问题,但要注意:如果fetchRelaysData后续会重复调用(比如定时拉取),那useEffect监听relaysData时的setRelay1(state_1)可能会覆盖用户手动切换的状态,需要根据业务逻辑处理这种冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:50:42