繁体   English   中英

反应上下文状态属性未定义

[英]React context state property is undefined

我正在尝试使用react的新上下文API,json作为数据,Providers,Consumers等动态构建Web应用程序菜单。我不知道出现错误。 但是首先这是一些代码:

上下文文件包括:

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;

菜单组件按如下方式使用此上下文:

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文件包含以下数据:

{
  "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
        }
      ]
    }
  ]
}

我在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"
},

.babelrc文件是:

{
  "presets": [
    ["es2016"],
    "react"
  ],
  "plugins": [
    "transform-class-properties"
  ]
}

此应用程序的编译运行没有错误,尽管我在运行控制台时遇到了javascript错误:

未捕获的TypeError:无法读取未定义的属性“ map”

这里要state.menu.sections的属性是state.menu.sections ,我要遍历并根据类型进行渲染。 如果我注释掉我用地图循环state.menu.sections的部分,则部分<h6>{state.menu.heading}</h6>可以正常工作,并且呈现<h6>Menu Heading</h6>而没有任何错误。 当我循环sections数组时,可能是什么问题?

试试这个代码:

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;

区别在于menu处于state ,而不是空的menu对象,您需要为其提供默认值。

注意:我不确定该错误,但是我认为这是因为javascript尝试在componentDidMount将新状态设置为您的state之前在state.menu.sections上使用map (因此state.menu.sections默认情况下是undefined的)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM