React中使用Context API获取数据返回undefined的问题排查
问题:使用React Context API时获取数据为undefined,报错“Cannot read properties of undefined (reading 'fileType')”
我在SourceComponent组件中尝试通过Context API获取fileType数据,但控制台打印CreateMappingData为undefined,同时出现报错“Cannot read properties of undefined (reading 'fileType')”。
SourceComponent.js 代码:
import React, {useContext} from "react"; import { MappingData } from "./DataProviders/MappingDataProvider"; import { Select } from '@appkit/react-components' const SourceComponent = () => { const CreateMappingData = useContext(MappingData); return ( <> {console.log('CreateMappingData',CreateMappingData)} // 此处CreateMappingData为undefined <div>Source</div> <div className="form-group"> <Select data={CreateMappingData.fileType} searchable={true} name="FileType" required={true} placeholder="File Type" valueKey="File Type" labelKey="File Type" ></Select> </div> </> ) } export default SourceComponent;
MappingDataProvider.js 代码:
import React, {useEffect, useState, createContext} from "react"; export const MappingData = createContext(); export const MappingDataProvider = ({children})=>{ const [fileType, setFileType] = useState([]); useEffect(()=> { fetchFileType(); }, []) const fetchFileType = () => { setFileType([ { value: 'client', label: 'Client' }, { value: 'project', label: 'Project' }, { value: 'user', label: 'User' }, ]) }; return( <MappingData.Provider value={{fileType}}> {children} </MappingData.Provider> ) }
错误原因
核心问题是**SourceComponent没有被包裹在MappingDataProvider的范围内**。React的useContext只能在Context Provider的后代组件中获取到正确的上下文值;如果组件不在Provider的包裹层级下,useContext会返回Context的默认值——这里创建Context时未传入默认值,所以结果是undefined。
解决方案
确保组件处于Provider包裹范围内
在父组件(比如App.js)中,用MappingDataProvider包裹住SourceComponent,示例代码:import SourceComponent from './SourceComponent'; import { MappingDataProvider } from './DataProviders/MappingDataProvider'; function App() { return ( <MappingDataProvider> <SourceComponent /> </MappingDataProvider> ); } export default App;可选:给Context设置默认值(避免undefined)
创建Context时可以传入一个默认值,这样即使组件暂时不在Provider范围内,也不会直接出现undefined:// 修改MappingDataProvider.js中的Context创建代码 export const MappingData = createContext({ fileType: [] });优化变量命名与解构
可以直接解构上下文值,让代码更简洁直观,同时避免因变量名混淆导致的问题:// 修改SourceComponent中的useContext调用 const { fileType } = useContext(MappingData); // 后续使用直接用fileType <Select data={fileType} ... />
内容的提问来源于stack exchange,提问作者Rajitha Ganji IN
相关产品推荐
相关产品推荐

