开发者问题收集

React 上下文状态属性未定义

2018-06-28
6563

我正在尝试使用 react 的新上下文 API、json 作为数据、提供者、消费者等动态构建 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 错误:

Uncaught TypeError: Cannot read property 'map' of undefined

这里讨论的属性是 state.menu.sections ,我想循环遍历并根据类型进行渲染。 如果我注释掉使用 map 循环 state.menu.sections 的部分,则 <h6>{state.menu.heading}</h6> 部分可以完美运行,并可以毫无错误地呈现 <h6>Menu Heading</h6> 。当我循环部分数组时可能存在什么问题?

1个回答

尝试此代码:

267431920

差异是 菜单 in state ,而不是空 菜单 对象,您需要为其提供默认值。

注意:我不确定错误,但我认为这是因为JavaScript尝试使用 map state.menu.sections componentDidmount 将新状态设置为 state (因此 state.menu.sections 将是 未定义的 默认情况下)

Lpaydat
2018-06-28