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

React中基于Server-Sent Events实现JSON部分字段更新的问题

问题根源

你的核心问题出在闭包捕获旧值和状态依赖错误:

  1. useEffect依赖数组为空,导致SSE订阅回调只会捕获组件挂载时的initialUserData初始值,后续Context更新用户数据后,回调里依然用旧的初始值进行合并,未更新字段无法保留最新状态。
  2. 代码中的for循环完全多余,对象展开运算符{...initialUserData, ...receivedData}已经完成了更新字段的合并操作。
修正方案(基于Context API)

假设你通过Context获取当前用户数据和更新方法,直接使用Context中的最新状态进行合并:

// 从Context中获取最新用户数据和更新方法
const { userData, updateUserData } = useContext(UserContext);
const [sessionState, setSessionState] = useState(false);

useEffect(() => {
  const unsubscribe = sse.subscribe('playerupdate', (d: any) => {
    // 基于Context的最新数据合并更新字段,未更新字段自动保留
    const updatedUserData = { ...userData, ...d };
    
    updateUserData(updatedUserData);

    // 注意:字段名需和后端返回一致,初始数据用的是id,这里PlayerId可能是笔误
    if (updatedUserData.id > 0) {
      setSessionState(true);
    } else if (updatedUserData.id === 0) {
      setSessionState(false);
    }
  });

  return unsubscribe;
}, [userData, updateUserData]); // 添加依赖,确保回调捕获最新的状态和方法
关键说明
  • 移除组件内维护的initialUserData,直接复用Context提供的userData,彻底避免闭包捕获旧值的问题。
  • 将userData和updateUserData加入useEffect依赖数组,每次Context状态更新时,订阅回调会重新创建,确保拿到最新数据。
  • 检查字段名一致性:初始数据里是id,但原代码判断用的是PlayerId,需和后端返回字段保持一致,否则会导致状态判断逻辑失效。
备选方案(若需保留组件内useState)

如果必须在组件内维护状态,使用函数式更新获取最新状态:

const [userData, setUserData] = useState({
  id: 1,
  name: 'Pol',
  color: 'black',
});
const [sessionState, setSessionState] = useState(false);

useEffect(() => {
  const unsubscribe = sse.subscribe('playerupdate', (d: any) => {
    // 函数式更新确保拿到最新的state值
    setUserData(prevData => {
      const updated = { ...prevData, ...d };
      
      if (updated.id > 0) {
        setSessionState(true);
      } else if (updated.id === 0) {
        setSessionState(false);
      }
      
      return updated;
    });
  });

  return unsubscribe;
}, []); // 无需添加依赖,函数式更新不依赖外部state

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 08:26:16