I am rendering table data in React JS and am having trouble getting my table row to go hidden on click of a child "delete" button. My current handler and render functions looks like this:
...
changeHandler: function(e) {
...
},
deleteHandler: function(e) {
e.currentTarget.closest("tr").style.visibility = "hidden";
},
render: function() {
return (
<div>
<div class="container">
<select onChange={ this.changeHandler.bind(this) }>
<option></option>
...
</select>
<table>
<thead>
<tr>
...
</tr>
</thead>
<tbody>
{data.map(function(row, j) {
return <tr key={j}>
<td>{row.text}</td>
<td><a href="" onClick={this.deleteHandler.bind(this, j)}>delete</a></td>
</tr>
}
)}
</tbody>
</table>
</div>
</div>
);
}
...
When I click on the delete anchor, I get this error in the console:
Uncaught TypeError: Cannot read property 'bind' of undefined
I don't understand why my delete handler isn't being recognized and bound, when the changeHandler
I'm using is. Could somebody please tell me how to get this event to hit the handler and how to target the parent tr to have it hidden?
After the correction in the typo above, I see that was not the error here. Check out the following fiddle to see it in action. There will be some need of style changes when you hide the row.
https://jsfiddle.net/vgo52rey/
The problem is with the binding of 'this' in the filter function in the fiddle. Abstract that out into another method so you can store the reference to this in a different variable, then you can keep the reference to this.delete or this.deleteHandler.
delete: function(e) {
e.currentTarget.closest("tr").style.visibility = "hidden";
},
renderRows: function() {
var shouldIRender =(row) => (this.state.filter === row.status || this.state.filter === "");
var self = this
return requests.filter(shouldIRender).map(function(row, j) {
return <tr key={j}>
<td style={tdStyle}>{row.title}</td>
<td style={tdStyle}>{row.status}</td>
<td style={tdStyle}>{row.created_at}</td>
<td style={tdStyle}>{row.updated_at}</td>
<td style={tdStyle}><a href="#" onClick={self.delete}>delete</a></td>
</tr>
}
)
},
in your render method now you can just supply this renderRows method return value:
<tbody>
{this.renderRows()}
</tbody>