luke luke - 1 month ago 22
Javascript Question

Remove table row after onClick in React component

I'm new to React and struggling on how to manipulate the DOM after I have deleted a record. I have a few react components but the one I am focused on is to delete a record in a rails api I have set up. I have the record deleting ok on the Ajax onclick call, but don't know the best way to remove the specific row using React.

Table full of data

var ContactAll = React.createClass({
getInitialState: function() {
return {
contacts: []
}
},
componentDidMount: function() {
$.ajax({
dataType: "json",
url: '/all-contacts',
type: "GET",
context: this,
success: function(data, status, xhr) {
this.setState({ contacts: data });
}
});
},
render: function(){
if(this.state.contacts == 0) {
return (
<div>Loading</div>
)
} else {
var contactComponents = this.state.contacts.map(function(contact, i) {
var full_name = contact.first_name + ' ' + contact.last_name

return <tr key={i} className="contact">
<td>{ full_name}</td>
<td></td>
<td>{ contact.email_address }</td>
<td>{ contact.phone_number }</td>
<td>{ contact.company_name }</td>
<td><DeleteButton email={contact.email_address} /></td>
</tr>;
});
return <div>
<table>
<tbody>
<tr>
<th>Contact Name</th>
<th></th>
<th>Email Address</th>
<th>Phone Number</th>
<th>Company Name</th>
</tr>

{contactComponents};

</tbody>
</table>
</div>
}
}
});


Delete Button within ContactAll component

var DeleteButton = React.createClass({
onClick: function() {
var email = this.props.email;

$.ajax({
data: {email_address: email },
url: '/delete-contact',
dataType: 'html',
type: "POST",
success: function(data, status, xhr) {
$('.delete-success').slideDown(400);
setTimeout(function() { $(".delete-success").slideUp(400); }, 5000);
}
});
},
render: function(){
return(
<button onClick={() => { this.onClick(this.props.email) }}>Delete</button>
)
}
});


What is the best way of removing the specific row that gets deleted when the delete button for the corresponding row is clicked?

Thanks!

Answer

Create a delete function and then send the index of the array into that and use splice to remove that array entry. Pass reference to this deleteRow function to the child component and call it from there like this.props.deleteRow(this.props.index); .Check out the complete code

like

deleteRow: function(index) {
    var contacts = [...this.state.contacts];
    contacts.splice(index, 1);
    this.setState({contacts});
  },

var ContactAll = React.createClass({
  getInitialState: function() {
    return {
      contacts: [] 
    }
  },
  componentDidMount: function() {
    $.ajax({
      dataType: "json",
      url: '/all-contacts',
      type: "GET",
      context: this,
      success: function(data, status, xhr) {
        this.setState({ contacts: data });
      }
    });
  },
  deleteRow: function(index) {
    var contacts = [...this.state.contacts];
    contacts.splice(index, 1);
    this.setState({contacts});
  },
  render: function(){
    if(this.state.contacts == 0) {
      return (
        <div>Loading</div>
      )
    } else {
      var contactComponents = this.state.contacts.map(function(contact, i) {
        var full_name = contact.first_name + ' ' + contact.last_name

        return  <tr key={i} className="contact">
                  <td>{ full_name}</td>
                  <td></td>
                  <td>{ contact.email_address }</td>
                  <td>{ contact.phone_number }</td>
                  <td>{ contact.company_name }</td>
                  <td><DeleteButton onClick ={this.deleteRow.bind(this)} index={i} email={contact.email_address} /></td>
                </tr>;
      }.bind(this));
      return <div>
              <table>
                <tbody>
                <tr>
                  <th>Contact Name</th>
                  <th></th>
                  <th>Email Address</th>
                  <th>Phone Number</th>
                  <th>Company Name</th>
                </tr>

                {contactComponents};

                </tbody>
              </table>
             </div>
    }
  }
}); 
var DeleteButton = React.createClass({
  onClick: function() {
    var email = this.props.email;
    this.props.deleteRow(this.props.index);
    $.ajax({
      data: {email_address: email },
      url: '/delete-contact',
      dataType: 'html',
      type: "POST",
      success: function(data, status, xhr) {
        $('.delete-success').slideDown(400);
        setTimeout(function() { $(".delete-success").slideUp(400); }, 5000);
      }
    });
  },
  render: function(){
    return(
      <button onClick={() => { this.onClick(this.props.email) }}>Delete</button>
    )
  }
});