1

I have some data that I can print them by .map() like this code

tabRow(){
   // CSS style for font Icon 
  const editIcon = {
    color: 'blue',
    fontSize: '1.3em',
    padding: '0 5px',
  };
  const trashIcon = {
    color: 'red',
    fontSize: '1.3em',
    padding: '0 5px',
  };
 if(this.state.products instanceof Array){
   return this.state.products.map(function(object, i){
       return(
        <tr key={ i }>
            <td>{ object.id }</td>
            <td>{ object.title }</td>
            <td>{ object.body }</td>
            <td width="200px">
          <Icon name="edit" onClick={() => this.handleClick(i)} style={editIcon}
           className="editIconClass" />
          <Icon name="trash" style={trashIcon} className="trashIconClass" />
        </td>
        </tr>
      )
   })
 }
}

I use tabRow() in the table body

<tbody>
   {this.tabRow()}
</tbody>

Also I have simple log in the handleClick() and also I bind this code in the constructor this.handleClick = this.handleClick.bind(this); I can see my view but when I click to run function i got this error:

Uncaught TypeError: Cannot read property 'handleClick' of undefined
    at onClick (app.js:61529)
    at HTMLUnknownElement.callCallback (app.js:40524)
    at Object.invokeGuardedCallbackDev (app.js:40562)
    at Object.invokeGuardedCallback (app.js:40611)
    at Object.invokeGuardedCallbackAndCatchFirstError (app.js:40625)
    at executeDispatch (app.js:40890)
    at executeDispatchesInOrder (app.js:40912)
    at executeDispatchesAndRelease (app.js:41010)
    at executeDispatchesAndReleaseTopLevel (app.js:41021)
    at forEachAccumulated (app.js:40991)

What I should do to fix it?

And my App.js file looks like this
require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';


import Master from './components/Master';
import CreateProduct from './components/CreateProduct';
import DisplayProduct from './components/DisplayProduct';
import UpdateProduct from './components/UpdateProduct';


render(
  <Router history={browserHistory}>
      <Route path="/" component={Master} >
        <Route path="/add-item" component={CreateProduct} />
        <Route path="/display-item" component={DisplayProduct} />
        <Route path="/edit/:id" component={UpdateProduct} />
      </Route>
    </Router>,
        document.getElementById('root'));

and my handleClick

handleClick(i){
  console.log('Click happened', i);
}
Nasser Ali Karimi
  • 4,462
  • 6
  • 34
  • 77

1 Answers1

3

You can't access this directly in the map function, you should bind it. You can do this in more than one way. For example, you can use an arrow function. This should be the code for your case:

return this.state.products.map((object, i) => (
     <tr key={ i }>
       ...
     </tr>
   ))

You could also add this as a second argument for the map function as described here.

César Landesa
  • 2,626
  • 1
  • 13
  • 18