[英]React context state property is undefined
I'm trying to build a web application menu dynamically using react's new context API, json as data, Providers, Consumers etc. I can't figure out an error I get. 我正在尝试使用react的新上下文API,json作为数据,Providers,Consumers等动态构建Web应用程序菜单。我不知道出现错误。 But first here's some code:
但是首先这是一些代码:
Context file includes: 上下文文件包括:
import React from 'react';
export const MenuContext = React.createContext();
class MenuProvider extends React.Component {
state = {
menu: {}
};
actions = {
fetchMenu: async() => {
const response = await fetch('/admin/json/menu.json');
const body = await response.json();
this.setState({
menu: body
});
}
}
componentDidMount() {
this.actions.fetchMenu();
}
render() {
return(
<MenuContext.Provider value={{state: this.state, actions: this.actions}}>
{this.props.children}
</MenuContext.Provider>
)
}
}
export default MenuProvider;
The menu component consumes this context as follows: 菜单组件按如下方式使用此上下文:
import React from 'react';
import {v1 as uuid} from 'uuid';
import MenuProvider, {MenuContext} from './contexts/menu';
import MenuDropdown from './parts/menu-dropdown';
import MenuItem from './parts/menu-item';
export default class SideMenu extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<header>
<MenuProvider>
<MenuContext.Consumer>
{({state}) => (
<React.Fragment>
<div className="cnt-menu-head">
<h6>{state.menu.heading}</h6>
</div>
<div className="cnt-menu">
<ul className="nav nav-pills flex-column">
{state.menu.sections.map((section, i) => {
if (section.type === 'link') {
return <MenuItem exact={section.exact} linkTo={section.linkTo} linkText={section.linkText}/>
} else if (section.type === 'dropdown') {
var keyedLinks = section.links.map((link) => {
link.key = uuid();
return link;
});
return <MenuDropdown key={uuid} linkText={section.linkText} links={keyedLinks}/>
}
})}
</ul>
</div>
</React.Fragment>
)}
</MenuContext.Consumer>
</MenuProvider>
</header>
);
};
};
menu.json file has this data: menu.json文件包含以下数据:
{
"heading": "Menu Heading",
"sections": [
{
"type": "link",
"linkText": "A Link",
"linkTo": "/",
"exact": true
},
{
"type": "dropdown",
"linkText": "System",
"links": [
{
"linkText": "System Table",
"linkTo": "/table/system",
"exact": false
},
{
"linkText": "Add System",
"linkTo": "/form/addsystem",
"exact": false
}
]
}
]
}
Versions of packages I use in package.json are: 我在package.json中使用的软件包版本为:
"devDependencies": {
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-es2016": "^6.24.1",
"babel-preset-react": "^6.24.1",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-router-dom": "^4.3.1",
"uuid": "^3.3.0"
},
And .babelrc
file is: .babelrc
文件是:
{
"presets": [
["es2016"],
"react"
],
"plugins": [
"transform-class-properties"
]
}
Compilation of this application runs without errors, though I get a javascript error in console when I run it: 此应用程序的编译运行没有错误,尽管我在运行控制台时遇到了javascript错误:
Uncaught TypeError: Cannot read property 'map' of undefined
未捕获的TypeError:无法读取未定义的属性“ map”
The property in question here is state.menu.sections
which I want to loop through and render based on type. 这里要
state.menu.sections
的属性是state.menu.sections
,我要遍历并根据类型进行渲染。 If I comment out the part I loop state.menu.sections
with map, the part <h6>{state.menu.heading}</h6>
works flawlessly and renders <h6>Menu Heading</h6>
without any errors. 如果我注释掉我用地图循环
state.menu.sections
的部分,则部分<h6>{state.menu.heading}</h6>
可以正常工作,并且呈现<h6>Menu Heading</h6>
而没有任何错误。 What may be the problem when I loop the sections array? 当我循环sections数组时,可能是什么问题?
Try this code: 试试这个代码:
import React from 'react';
export const MenuContext = React.createContext();
class MenuProvider extends React.Component {
state = {
menu: { heading: '', sections: [] }
};
actions = {
fetchMenu: async() => {
const response = await fetch('/admin/json/menu.json');
const body = await response.json();
this.setState({
menu: body
});
}
}
componentDidMount() {
this.actions.fetchMenu();
}
render() {
return(
<MenuContext.Provider value={{state: this.state, actions: this.actions}}>
{this.props.children}
</MenuContext.Provider>
)
}
}
export default MenuProvider;
The difference is menu
in state
, instead of empty menu
object, you need to provide it with default values. 区别在于
menu
处于state
,而不是空的menu
对象,您需要为其提供默认值。
NOTE: I not sure about the error, but I think it is because javascript try to use map
on state.menu.sections
before the componentDidMount
set new state to your state
(so the state.menu.sections
will be undefined
by default) 注意:我不确定该错误,但是我认为这是因为javascript尝试在
componentDidMount
将新状态设置为您的state
之前在state.menu.sections
上使用map
(因此state.menu.sections
默认情况下是undefined
的)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.