React Context调用setState后useState仍为undefined问题求助
React Context setState后state仍为undefined的问题解答
问题1:调用setOnButtonStateChanged后,handleChange为何被无参调用?
控制台第2行的undefined undefined undefined是handleChange的执行输出,说明该函数被无参触发了。结合你的场景,核心原因是:
你省略的Context内部游戏手柄监听逻辑中,存在自动调用onButtonStateChanged的代码。比如在手柄连接、按钮状态变化的监听回调里,当onButtonStateChanged被设置后,某个事件触发了它的调用,但未传入正确参数。
另外,如果你曾给onButtonStateChanged设置console.log作为默认值,console.log本身会在初始化时执行,但当前代码初始值为undefined,所以更可能是手柄监听逻辑误触发了函数调用。
问题2:onButtonStateChanged设置后仍为undefined
这个问题的关键是你在Context的useMemo中引用了未定义的setOnGamepadConnected变量:
// Context.js 中的错误代码片段 const value = useMemo(() => { return { // ...其他属性 setOnGamepadConnected // 该变量未在组件内声明! } }, [ // ...其他依赖 setOnGamepadConnected // 同样未定义 ])
这会导致两个严重问题:
- 组件渲染时会抛出隐式的
ReferenceError(可能被你忽略),导致Context Provider无法正常工作; useMemo因依赖项异常,无法正确缓存上下文值,每次渲染都会生成新的上下文对象,最终让setOnButtonStateChanged的调用无法正确更新onButtonStateChanged状态。
修复方案
1. 移除未定义的setOnGamepadConnected引用
如果不需要这个属性,直接从useMemo的返回值和依赖数组中删除;如果是笔误(比如应为setGamepadsCount),修正为正确的setter函数。修改后的代码:
const value = useMemo(() => { return { gamepads, mappedGamepads, playerCount: mappedGamepads?.length, setOnButtonStateChanged // 移除 setOnGamepadConnected } }, [ gamepads, mappedGamepads, setOnButtonStateChanged // 移除 setOnGamepadConnected ])
2. 排查handleChange被调用的原因
检查Context中所有引用onButtonStateChanged的地方,确保只有在手柄按钮状态真正变化时才调用它,并且传入完整参数:
// 示例:正确的手柄按钮事件处理逻辑 const handleGamepadButtonChange = (button, isPressed, index) => { if (onButtonStateChanged) { onButtonStateChanged(button, isPressed, index); } };
3. 优化Context初始化与服务端渲染逻辑
- 给Context设置默认值,避免组件在Provider外渲染时出现
undefined:const PlayerGamepadContext = createContext({ gamepads: [], mappedGamepads: [], playerCount: 0, setOnButtonStateChanged: () => {} }); - 服务端渲染时返回
null或加载组件,避免hydrate不匹配:if (typeof window === 'undefined') { return null; // 或自定义 <Loading /> 组件 }
内容的提问来源于stack exchange,提问作者Maxime
相关产品推荐
相关产品推荐

