Phat Baba
Phat Baba

Reputation: 53

How to delete item on click in React

I am trying to delete an item in React by clicking on a button. Currently my code returns Cannot read properties of undefined (reading 'ProductID') and I am not sure why since I am accessing it via an id and it should work. How can I properly make my code work and delete the item on click? Here is my attempt:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Grid, GridColumn as Column } from '@progress/kendo-react-grid';
import { sampleProducts } from './sample-products';

const allInEdit = sampleProducts.map((item) =>
  Object.assign(
    {
      inEdit: true,
    },
    item
  )
);

const deleteItem = (item) => {
  let index = sampleProducts.findIndex(
    (record) => record.ProductID === item.ProductID
  );
  data.splice(index, 1);
  return sampleProducts;
};

const MyCommandCell = () => {
  return (
    <button
      className="k-button k-grid-remove-command"
      onClick={() => deleteItem()}
    >
      Remove
    </button>
  );
};

const App = () => {
  const [data, setData] = React.useState(allInEdit);

  const itemChange = (e) => {
    let newData = data.map((item) => {
      if (item.ProductID === e.dataItem.ProductID) {
        item[e.field || ''] = e.value;
      }

      return item;
    });
    setData(newData);
  };

  return (
    <Grid data={data} editField="inEdit" onItemChange={itemChange}>
      <Column field="ProductID" title="Id" width="50px" editable={false} />
      <Column field="ProductName" />
      <Column field="FirstOrderedOn" editor="date" format="{0:d}" />
      <Column field="UnitsInStock" width="150px" />
      <Column field="Discontinued" width="50px" editor="boolean" />
      <Column cell={MyCommandCell} width="240px" />
    </Grid>
  );
};

ReactDOM.render(<App />, document.querySelector('my-app'));

Upvotes: 1

Views: 3594

Answers (1)

Ahmet Emre Kilinc
Ahmet Emre Kilinc

Reputation: 6925

You should move your deleteItem and MyCommandCell functions inside your App component in order to to use setData. You also need to read current row's data from dataItem of current row's item. That value should be passed to the deleteItem function as a prop

You can use this code:

import * as React from "react";
import * as ReactDOM from "react-dom";
import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";
import { sampleProducts } from "./sample-products";

const allInEdit = sampleProducts.map((item) =>
  Object.assign(
    {
      inEdit: true
    },
    item
  )
);

const App = () => {
  const [data, setData] = React.useState(allInEdit);

  const deleteItem = (item) => {
    let newProducts = data.filter(
      (record) => record.ProductID !== item.ProductID
    );
    setData(newProducts);
  };

  const MyCommandCell = (item) => {
    return (
      <button
        className="k-button k-grid-remove-command"
        onClick={() => deleteItem(item.dataItem)}
      >
        Remove
      </button>
    );
  };

  const itemChange = (e) => {
    let newData = data.map((item) => {
      if (item.ProductID === e.dataItem.ProductID) {
        item[e.field || ""] = e.value;
      }

      return item;
    });
    setData(newData);
  };

  return (
    <Grid data={data} editField="inEdit" onItemChange={itemChange}>
      <Column field="ProductID" title="Id" width="50px" editable={false} />
      <Column field="ProductName" />
      <Column field="FirstOrderedOn" editor="date" format="{0:d}" />
      <Column field="UnitsInStock" width="150px" />
      <Column field="Discontinued" width="50px" editor="boolean" />
      <Column cell={MyCommandCell} width="240px" />
    </Grid>
  );
};

ReactDOM.render(<App />, document.querySelector("my-app"));

You can take a look at this sandbox for live working example.

Upvotes: 1

Related Questions