Search code examples
javascriptjsonreactjshide

Using react, how would I hide a table row on click?


Hey guys I am using this table to display data and I added a button to each row. How would I be able to hide a row when I click the hide button next to it?

I am aware of a way to do within html elements but not sure how to hide a particular row within a table thats within a loop

Can anyone show me how to accomplish this?

Thank you

import React, { Component } from 'react'

class Table extends Component {
   constructor(props) {
      super(props) //since we are extending class Table so we have to use super in order to override Component class constructor
      this.state = { //state is by default an object
         students: [
            { id: 1, name: 'Wasif', age: 21, email: 'wasif@email.com' },
            { id: 2, name: 'Ali', age: 19, email: 'ali@email.com' },
            { id: 3, name: 'Saad', age: 16, email: 'saad@email.com' },
            { id: 4, name: 'Asad', age: 25, email: 'asad@email.com' }
         ]
      }
   }

   renderTableData() {
    return this.state.students.map((student, index) => {
       const { id, name, age, email } = student //destructuring
       return (
          <tr key={id}>
             <td>{id}</td>
             <td>{name}</td>
             <td>{age}</td>
             <td>{email}</td>
             <td><button>HIDE</button></td>
          </tr>
       )
    })



 }
renderTableHeader() {
      let header = Object.keys(this.state.students[0])
      return header.map((key, index) => {
         return <th key={index}>{key.toUpperCase()}</th>
      })
   }







   render() { //Whenever our class runs, render method will be called automatically, it may have already defined in the constructor behind the scene.
    return (
      <div>
         <h1 id='title'>React Dynamic Table</h1>
         <table id='students'>
            <tbody>
               <tr>{this.renderTableHeader()}</tr>
               {this.renderTableData()}
            </tbody>
         </table>
      </div>
   )
}
}

export default Table 

Solution

  • You could add an onClick handler to the button that adds a property that determines the student should be hidden or not.

    Notice the onClick={() => this.hideRow(id)} below.

    renderTableData() {
      return this.state.students.map((student, index) => {
        const { id, name, age, email, isHidden } = student; //destructuring
    
        // isHidden will default to undefined if not found on the student object
        
        // user is hidden
        if (isHidden === true) {
          return null;
        }
    
        return (
          <tr key={id}>
            <td>{id}</td>
            <td>{name}</td>
            <td>{age}</td>
            <td>{email}</td>
            <td>
              <button onClick={() => this.hideRow(id)}>HIDE</button>
            </td>
          </tr>
        );
      });
    }
    

    The hideRow method will accept a student id and will add an isHidden: true attribute to the student with that id.

    hideRow(id) {
      const students = this.state.students.map((student) => {
        // not same id? leave as is
        if (student.id !== id) {
          return student;
        }
    
        return { ...student, isHidden: true };
      });
    
      this.setState({ students });
    }
    

    Now you don't want to display the isHidden column, so you have to update renderTableHeader method to skip that.

    renderTableHeader() {
      let header = Object.keys(this.state.students[0]);
      return header.map((key, index) => {
       
        // notice this
        if (key === "isHidden") {
          return null;
        }
    
        return <th key={index}>{key.toUpperCase()}</th>;
      });
    }
    

    Edit musing-cherry-y7i5c