Reputation: 10947
I am trying to make a table row function like a Link
with react-router
.
I keep getting the error Cannot read property 'handleClick' of undefined
handleClick(user) {
this.router.transitionTo('index', user);
}
render(){
var userNodes = this.props.posts.map(function(user, i){
return (
<tr onClick={() => this.handleClick(user)}>
<Td>{user.postId}</Td>
<Td>{user.title}</Td>
<Td>{user.body}</Td>
</tr>
)
});
...
Upvotes: 3
Views: 1911
Reputation: 104369
Its a binding
issue, you need to bind
the context otherwise this
will not point to the react component. Either use .bind(this)
with function
or use arrow function
to avoid this kind of problem. Use this:
render(){
var userNodes = this.props.posts.map(function(user, i){
return (
<tr onClick={() => this.handleClick(user)}>
<Td>{user.postId}</Td>
<Td>{user.title}</Td>
<Td>{user.body}</Td>
</tr>
)
}.bind(this));
Or this:
render(){
var userNodes = this.props.posts.map((user, i) => {
return (
<tr onClick={() => this.handleClick(user)}>
<Td>{user.postId}</Td>
<Td>{user.title}</Td>
<Td>{user.body}</Td>
</tr>
)
});
Check the working example:
class App extends React.Component{
handleClick(user){
console.log(user);
}
render(){
var data = [0,1,2,3,4].map((user, i) => {
return (
<tr onClick={() => this.handleClick(user)}>
<td>{user}</td>
<td>{user}</td>
<td>{user}</td>
</tr>
)
});
return(
<table>
<thead>
<th>A</th>
<th>B</th>
<th>C</th>
</thead>
<tbody>
{data}
</tbody>
</table>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
Upvotes: 1
Reputation: 6674
Use arrow function as map
callback to preserve component context (otherwise this
inside the callback will not point to the component instance):
render(){
var userNodes = this.props.posts.map((user, i) => {
return (
<tr onClick={() => this.handleClick(user)}>
<Td>{user.postId}</Td>
<Td>{user.title}</Td>
<Td>{user.body}</Td>
</tr>
)
});
Upvotes: 4
Reputation: 81
You have to bind it.
var userNodes = this.props.posts.map(function(user, i){}.bind(this));
Upvotes: 0