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>
)
}
}
Related videos on Youtube
Author by
Mr.Noob
Updated on June 01, 2022Comments
-
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 over 6 yearsbecause you need to bind the function
createMenuListItem
withthis
. -
Mr.Noob over 6 yearsi tried adding this in constuctor this.createMenuListItem = this.createMenuListItem.bind() but i get following error"Cannot read property 'bind' of undefined"
-
Cyril Cherian over 6 yearsthis is wrong ` this.createMenuListItem.bind()` should be
this.createMenuListItem = this.createMenuListItem.bind(this)
-
Mr.Noob over 6 yearsstill i get the same error "Cannot read property 'bind' of undefined"
-
-
Mr.Noob over 6 yearscreateMenuListItem calls another function. when i move both the functions outside render method. I get function is not defined error
-
mersocarlin over 6 years@Mr.Noob so maybe share a bit more of your code :)
-
Mr.Noob over 6 yearsadded complete code
-
Mr.Noob over 6 yearsWorked thanks....had to convert to even the map method inside function into arrow