1

I'm building a sidebar menu with submenu levels, and I'm using this code to build the menu and the submenus:

Sidebar menu:

import React from 'react';

import SidebarMenuItem from './SidebarMenuItem';

var menuData = require("./data/menu.json");

class SidebarMenu extends React.Component {
    constructor(props) 
    {
        super(props);

        this.state = { expanded: true };
    };


  render() {

      return (
        <div>
          {
            menuData.map((item, index) => <SidebarMenuItem id={ index.toString()} key={index.toString()} {...item} />)
          }
        </div>
      );
  };
}

export default SidebarMenu;

SidebarMenuItem:

import React from 'react';

class SidebarMenuItem extends React.Component {

    render() {

        console.log(this.props.id);

        return (
            <div>
                <a href={this.props.link}>{this.props.title}<i className={'fa ' + this.props.icon}/></a>

                {this.props.submenu ? this.props.submenu.map((subitem, index) => <SidebarMenuItem key={this.props.id + index.toString()} {...subitem} />) : null }

            </div>
            )
    }

}

SidebarMenuItem.propTypes = {
    id: React.PropTypes.string,
    key: React.PropTypes.string,
    title: React.PropTypes.string,
    ref: React.PropTypes.string,
    icon: React.PropTypes.string,
    submenu: React.PropTypes.array
}

export default SidebarMenuItem;

Although I can see the submenus on screen, I'm getting the following error:

Warning: SidebarMenuItem: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop.

Another clue that something is wrong is the console output:

0
1 
undefined <-- I was supposed to get 11 and 12 here, as this option has 2 submenus
2

And finally my menu.JSON data:

[
  { 
    "title": "Option1",
    "link": "www.google.com",
    "icon": "fa-edit"
  },
  {
    "title": "Option2",
    "link": "",
    "icon": "fa-hello",
    "submenu": 
    [
      {
        "title": "SubOption2.1",
        "link": "wwww.yahoo.com",
        "icon": "fa-asterisk"
      },
      {
        "title": "SubOption2.2",
        "link": "wwww.tisafe.com",
        "icon": "fa-save"
      }
    ]
  },
  {
    "title": "Option3",
    "link": "www.mezasoft.com",
    "icon": "fa-save"
  }
]

Help appreaciated to find out what's wrong with my code.

1
  • 1
    You can't have a prop named 'key'. This name is reserved for react internal use Commented Jan 22, 2017 at 18:02

1 Answer 1

2

You are getting the warning because key is a restricted attribute and cannot be passed as a prop, change it to keyValue. Also you get undefined when you use this.props.id because in your SidebarMenuItem render function for submenus you are still calling the same component and there you are not passing the id as a prop. you can see that in the snippet below. I hope it helps

class SidebarMenu extends React.Component {
    constructor(props) 
    {
        super(props);

        this.state = { expanded: true };
    };


  render() {
      var menuData = [
  { 
    "title": "Option1",
    "link": "www.google.com",
    "icon": "fa-edit"
  },
  {
    "title": "Option2",
    "link": "",
    "icon": "fa-hello",
    "submenu": 
    [
      {
        "title": "SubOption2.1",
        "link": "wwww.yahoo.com",
        "icon": "fa-asterisk"
      },
      {
        "title": "SubOption2.2",
        "link": "wwww.tisafe.com",
        "icon": "fa-save"
      }
    ]
  },
  {
    "title": "Option3",
    "link": "www.mezasoft.com",
    "icon": "fa-save"
  }
];
      return (
        <div>
          {
           menuData.map((item, index) => <SidebarMenuItem id={ index.toString()} keyValue={index.toString()} {...item} />)
          }
        </div>
      );
  };
}

class SidebarMenuItem extends React.Component {

    render() {

        console.log('in render',this.props);

        return (
            <div>
                <a href={this.props.link}>{this.props.title}<i className={'fa ' + this.props.icon}/></a>

                {this.props.submenu ? this.props.submenu.map((subitem, index) => <SidebarMenuItem keyValue={this.props.id + index.toString()} {...subitem} />) : null }

            </div>
            )
    }

}

SidebarMenuItem.propTypes = {
    id: React.PropTypes.string,
    keyValue: React.PropTypes.string,
    title: React.PropTypes.string,
    ref: React.PropTypes.string,
    icon: React.PropTypes.string,
    submenu: React.PropTypes.array
}

ReactDOM.render(<SidebarMenu/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app"></div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.