Tyler Morales
Tyler Morales

Reputation: 1830

How to delete a row from a HTML table with React?

I am trying to delete a row inside a HTML table using React. I have an onClick handler on a delete button inside the row I would like to delete, but how can I target that specfic row to delete? I pass along a site variable with an unique id attribute. Maybe that helps?

// table component

export default function IndexPage() {
  const site = { id: 123 };
  const removeSite = async ({ id, e }) => {
    console.log(e.target);
  };
  return (
    <table>
      <tbody>
        <tr>
          <th>Name</th>
        </tr>
        <tr>
          <td>Valles Caldera National Preserve</td>
          <button onClick={(e) => removeSite(site,e )}>Delete</button>
        </tr>
      </tbody>
    </table>
  );
}

Here is a link to a code sandbox.

Upvotes: 0

Views: 993

Answers (3)

Hamid
Hamid

Reputation: 63

React best pattern for any update is using state variables. So if you need to update a table, you should use a state array variable to store data of rows of table, for example tableRows, and using .map() to create table rows from this variable. Now if you update this variable using for example setTableRows([...newVariable]), this will automatically update your table.

UPDATE based on your update:

Should update your code like this:

export default function IndexPage() {
  const [sites, setSites] = [{ id: 123,name:"Valles Caldera National Preserve" }];

  const removeSite = (id) => {
    // do more staff like deleting from database

    // you may need to iterate through new array, because direct updating of state array variables do not force to re-render because of some reasons.
    setSites([...sites.filter(site => site.name !== id)]);
  };

  return (
    <table>
      <tbody>
        <tr>
          <th>Name</th>
        </tr>
        {map.sites((site) => {
          return (
            <tr>
              <td>{site.name}</td>
              <button onClick={() => removeSite(site.id)}>Delete</button>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

Upvotes: 1

jesvin palatty
jesvin palatty

Reputation: 373

The better way to implement this will be to display using an Array and giving ids to individual row items ->

Your code will be something like this then ->

const [dataArray, setDataArray] = useState([
    { name: "Valles Caldera National Preserve", id: 1 },
    { name: "Tyler Morales", id: 2 },
  ]);

  const removeSite = async (id) => {
    setDataArray((data) => data.filter((dataEach) => dataEach.id !== id));
  };

  return (
    <table>
      <tbody>
        <tr>
          <th>Name</th>
        </tr>
        {dataArray.map((data) => (
          <tr key={data.id}>
            <td>{data.name}</td>
            <button onClick={(e) => removeSite(data.id)}>Delete</button>
          </tr>
        ))}
      </tbody>
    </table>
  );

Upvotes: 3

adrian
adrian

Reputation: 2846

Without more information, I'll assume you plan to map over the data to generate each row.

If you're using an API to fetch the data, you could leverage the useEffect hook to fetch the data and set it to a state variable with the useState hook to manage the visible rows, something like:

export default function IndexPage() {

  const [sites,setSites] = [];
  useEffect(()=>{
    // Fetch your data here and pass it to setSites to set state
    // For example, setState([{ id: 123,name:"Valles Caldera National Preserve" }]) 
  },[])

  const removeSite = async ({ id, e }) => {
    // Below we update state to be the original array, less the clicked row
    setSites(sites.filter(site =>site.name !== id));
  };
  return (
    <table>
      <tbody>
        <tr>
          <th>Name</th>
        </tr>
        {map.sites((site) => {
          return (
            <tr>
              <td>{site.name}</td>
              <button onClick={(e) => removeSite(site.id, e)}>Delete</button>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}



Upvotes: 2

Related Questions