React使用Context报错Cannot destructure property 'selected'解决方案
React Context 解构undefined报错修复
错误信息
React应用使用Context功能时触发运行时错误,报错内容如下:
Uncaught TypeError: Cannot destructure property 'selected' of 'Object(...)(...)' as it is undefined.
错误触发位置为InputsList组件内的代码行:
const { selected, setSelected } = useContext(ParamsContext);
涉及的问题代码片段:
- Context定义
import { createContext } from 'react'; export const ParamsContext = createContext({ selected: [], setSelected: () => {}, textName: null, valueName: null });
- Provider所在的InputParams组件
import React, { useState } from 'react'; import InputsList from './InputsList'; import { ParamsContext } from './services/ParamsContext'; function InputParams(props) { const [selected, setSelected] = useState([]); const textName = "test"; const valueName = "test2"; return ( <div> <ParamsContext.Provider selected={selected} setSelected={setSelected} textName={textName} valueName={valueName}> <InputsList /> </ParamsContext.Provider> </div> ); } export default InputParams;
- 消费Context的InputsList组件
import React, { useContext } from 'react'; import { ParamsContext } from './services/ParamsContext'; function InputsList(props) { const { selected, setSelected } = useContext(ParamsContext); return ( <div> {selected.length} </div> ); } export default InputsList;
错误根因
核心问题是ParamsContext.Provider的传值写法不符合React API规则:
React Context的Provider组件仅接收名为value的prop作为向下传递的上下文内容,现有代码直接把selected/setSelected等字段作为独立属性写在Provider标签上,这些属性不会被Context识别为要传递的内容。
这里有个高频踩坑点:createContext时传入的默认值,只有当组件树中完全不存在对应Context的Provider时才会生效。只要代码中写了Provider但没有传入合法的value属性,useContext()的返回值就是undefined,对undefined做解构取值就会抛出你看到的类型错误。
修复方案
修改InputParams组件中Provider的写法,把所有要向下传递的上下文字段统一包裹在value prop中即可,修正后的Provider代码:
<ParamsContext.Provider value={{ selected: selected, setSelected: setSelected, textName: textName, valueName: valueName }}> <InputsList /> </ParamsContext.Provider>
React 17及以上版本支持对象属性简写,当对象key和赋值的变量名完全相同时,可以简化写法:
<ParamsContext.Provider value={{ selected, setSelected, textName, valueName }}> <InputsList /> </ParamsContext.Provider>
后续排查点
如果修改后仍有报错,可以按以下顺序定位问题:
- 确认消费Context的
InputsList组件写在Provider的子树内部,不要把消费组件放在Provider标签外层 - 确认两个组件导入
ParamsContext的路径完全一致,避免出现重复定义Context、路径拼写错误导致拿到不同Context实例的问题 - 临时在
useContext调用位置加打印console.log(useContext(ParamsContext)),确认返回值是否为预期的对象结构,快速定位传值链路断裂的位置
内容的提问来源于stack exchange,提问作者user165210
相关产品推荐
相关产品推荐

