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

React父组件更新Context后子组件仍获取undefined问题排查

问题分析与解决方案

你的问题出在几个细节上,逐个排查修复:

1. fetch未解析JSON数据

你在GameIndex.tsx的useEffect里直接把fetch返回的data传给setLobby,但fetch返回的是Response对象,不是后端返回的JSON数据。这会导致lobby存的是Response对象而非你需要的ILobby数据,在Scoreboard里直接渲染时可能显示异常,看起来像undefined。

修复代码:

useEffect(() => {
  // 先判断lobbyId存在再请求,避免无效请求
  if (!lobbyId) return;
  
  fetch(`http://localhost:8080/api/lobby/${lobbyId}`)
    // 第一步:解析Response为JSON格式
    .then(res => {
      // 可选:检查请求是否成功,提前捕获错误
      if (!res.ok) throw new Error(`请求失败:${res.status}`);
      return res.json();
    })
    .then(data => setLobby(data))
    // 增加错误处理,方便排查问题
    .catch(err => console.error('获取 lobby 失败:', err));
}, [lobbyId, setLobby]);

2. useEffect依赖项错误

你原来的依赖项是[lobby, setLobby],这会导致每次lobby更新时,useEffect都会重新执行fetch,陷入无限循环——fetch更新lobby,lobby变化触发useEffect再次fetch,反复执行后可能导致数据异常。

把依赖项改成[lobbyId, setLobby],只有当lobbyId变化时才重新请求,符合业务逻辑。

3. Context默认值类型不匹配

在LobbyContext.tsx里,你给lobby的默认值是""(字符串),但接口定义的是ILobby | undefined,类型不匹配可能导致运行时的隐性问题。

修正默认值:

export const LobbyContext = createContext<ILobbyContext>({
    lobby: undefined, // 改为undefined,符合接口定义
    setLobby: () => {
        console.log("old function")
    }
});

4. 确保lobbyId正确获取

你的页面是/game/[id].tsx,lobbyId应该来自路由参数。如果没正确获取,会导致请求URL错误,后端返回无效数据,最终lobby可能是undefined。

在GameIndex.tsx里添加路由参数获取(以Next.js为例):

import { useRouter } from 'next/router';

const GameIndex = () => {
  const router = useRouter();
  const { id: lobbyId } = router.query;
  const { lobby, setLobby } = useContext(LobbyContext);

  // 后续的useEffect使用这个lobbyId
  // ...
}

验证修复

做完以上修改后:

  • GameIndex里的fetch会正确获取并解析后端的ILobby数据,更新Context
  • Scoreboard作为GameIndex的子组件,会从Context拿到正确的lobby值
  • 避免了无限循环和类型不匹配的隐性问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:58:11