Im learning react and now for my project I need pass props from my User component to my Main Component. I get this mistake every time i try to do it like guy on this video :
handleSelectedUser(user){
console.log(this.state);
}
render() {
let users;
let selectElem = this.selectElement;
if (this.state.displayedUsers) {
users = this.state.displayedUsers.map(function (usr) {
return (
<User key={usr.contact.phone} user={usr} someInfo={this.handleSelectedUser.bind(this)}/>
//this one throwing this mistake: "ContactsApp.js:44 Uncaught TypeError: Cannot read property 'handleSelectedUser' of undefined"
);
});
}
return (
<div>
<div className="left-column">
<div className="users">
<SearchUser handleEvent= {this.handleSearch.bind(this)} />
<ul className="usersList"> {users} </ul>
</div>
</div>
<div className="right-column">
<ContactDetail someInfo={this.handleSelectedUser.bind(this)} selectedUser={this.props.items[3]} /> //this element works well
</div>
</div>
);
}
}
User component and ContactDetail component have the same method that adds a someInfo prop to it, but only ContactDetail works well. What might be the problem?
excellent choice choosing to learn React and great instructor you choose. Your problem was not the React logic itself, but you made a JavaScript mistake, an ES6 one to be exact. This is your current code:
if (this.state.displayedUsers) {
users = this.state.displayedUsers.map(function (usr) {
return (
<User key={usr.contact.phone} user={usr} someInfo={this.handleSelectedUser.bind(this)}/>
//this one throwing this mistake: "ContactsApp.js:44 Uncaught TypeError: Cannot read property 'handleSelectedUser' of undefined"
);
});
}
Now as you can see the error you get is
Cannot read property 'handleSelectedUser' of undefined"
And how do you call it?
this.handleSelectedUser.bind(this)
That means that undefined in the error above is this
Why does that happen? When you map through an array it is a common pracitce to use an arrow function instead of an unnamed function, like this:
users = this.state.displayedUsers.map((usr) => {
return (
<User key={usr.contact.phone} user={usr} someInfo={this.handleSelectedUser.bind(this)}/>
//this will now work
);
});
Difference is that () => {has acces to this }, but function() {dosent have acces to this }
Use an =>
instead of function
in your map function like this
users = this.state.displayedUsers.map(usr => {
return (
<User key={usr.contact.phone} user={usr} someInfo={this.handleSelectedUser.bind(this)}/>
);
});
But why though? In short the this
keyword is referring to the anonymous function you created inside of your map function. While the =>
symbol make's the scope transparent so this
would behave as you would expect.
I know that doesn't explain the entire picture but, hopefully it provides enough insight to deal with this solution. You may want to consider doing more research on this topic.
Another solution could be assigning a temporary variable to this
like so var self = this;
and then use self
from there on.
PS The .bind() you are adding to your function is also another way to resolve this issue but, it would require some additional refactoring.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.