3

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>
       )
   });
...
0

3 Answers 3

4

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>
       )
   });
Sign up to request clarification or add additional context in comments.

Comments

1

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'/>

Comments

0

You have to bind it.

var userNodes = this.props.posts.map(function(user, i){}.bind(this));

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.