this.state is undefined inside function - React JS

11,532

By using function you sort of lose the context and this is not the one you were expecting.

In this case, either use arrow function as:

render() {
  createMenuItems = (items) => {
    console.log(this.state.menuSelected)
    ...
  }
}

Or, and here comes my suggestion, move createMenuItems outside of render method:

createMenuItems = (items) => {
  console.log(this.state.menuSelected)
}

render() {
  return (
    <nav id='sidebar'>
      <ul className='list-unstyled'>
        {menumenuOptions.menuItems.map((menuItem, index) =>
          this.createMenuListItem(menuItem)
        )}
      </ul>
    </nav>
  )
}

Binding it in the constructor is also a possibility:

class YourComponent extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      menuSelected: '',
    }

    this.createMenuListItem = this.createMenuListItem.bind(this)
  }

  createMenuListItem() {
    console.log(this.state.menuSelected)
  }

  render() {
    return (
      <nav id='sidebar'>
        <ul className='list-unstyled'>
          {menumenuOptions.menuItems.map((menuItem, index) =>
            this.createMenuListItem(menuItem)
          )}
        </ul>
      </nav>
    )
  }
}
Share:
11,532

Related videos on Youtube

Mr.Noob
Author by

Mr.Noob

Updated on June 01, 2022

Comments

  • Mr.Noob
    Mr.Noob almost 2 years

    Why do i get state is undefined here? I tried various solutions but none worked for me. Can someone point out what am doing wrong here

    Edit:

    Complete Code of the component

      class Sidebar extends React.Component {
        constructor (props) {
          super(props)
          this.state = {
            menuSelected: menuOptions.menuItems[0].title,
          }
          this.createMenuListItem = this.createMenuListItem.bind(this)
        }
        render () {
          console.log(this.state.menuSelected)
          function getChildItems (child) {
            let childItems = child.children.map(function (menuItem, index) {
              return createMenuListItem(menuItem)
            })
            return (
              <li key={child.title} className='dropdown'>
                <i className={child.iconName} />
                <span className='dropdown-toggle'>{child.title}</span>
                <ul className=''>
                  {childItems}
                </ul>
              </li>
            )
          }
          function createMenuListItem (menuItem) {
            if (menuItem.hasChild === 'N') {
              console.log(this.state.menuSelected)
              return (
                <li key={menuItem.title}>
                  <a href='#'>
                    <i className={menuItem.iconName} />
                    <span>{menuItem.title}</span>
                  </a>
                </li>
              )
            } else {
              return getChildItems(menuItem)
            }
          }
    
          let menuItemsLoaded = menuOptions.menuItems.map((menuItem, index) => {
            return createMenuListItem(menuItem)
          })
          return (
            <nav id='sidebar'>
              <ul className='list-unstyled'>
                {menuItemsLoaded}
              </ul>
            </nav>
          )
        }
      }
    
      export default Sidebar
    

    Also can somebody possibly suggest a better option when the sidebar content is loaded dynamically from the server

    • Cyril Cherian
      Cyril Cherian over 6 years
      because you need to bind the function createMenuListItem with this.
    • Mr.Noob
      Mr.Noob over 6 years
      i tried adding this in constuctor this.createMenuListItem = this.createMenuListItem.bind() but i get following error"Cannot read property 'bind' of undefined"
    • Cyril Cherian
      Cyril Cherian over 6 years
      this is wrong ` this.createMenuListItem.bind()` should be this.createMenuListItem = this.createMenuListItem.bind(this)
    • Mr.Noob
      Mr.Noob over 6 years
      still i get the same error "Cannot read property 'bind' of undefined"
  • Mr.Noob
    Mr.Noob over 6 years
    createMenuListItem calls another function. when i move both the functions outside render method. I get function is not defined error
  • mersocarlin
    mersocarlin over 6 years
    @Mr.Noob so maybe share a bit more of your code :)
  • Mr.Noob
    Mr.Noob over 6 years
    added complete code
  • Mr.Noob
    Mr.Noob over 6 years
    Worked thanks....had to convert to even the map method inside function into arrow