Reinaldo Pastran
Reinaldo Pastran

Reputation: 81

Why is my react Table not updating the data?

I got a react Table that I want to delete or modify my data. My code is below for all my cells.

    deleteTableElement = (row) => {
        let data = this.state.list.data;
        data.splice(row.id, 1);
        this.setState({
            list:{
                ...this.state.list,
                data:data
            }
        })
    };

    actionsCell = (columns) => {
        columns.push({
            Header: "Accion",
            Cell: (props) => {
                console.log(props);
                return (
                    <div
                        style={{
                            display: "flex",
                            justifyContent: "space-around",
                        }}
                    >
                        <i
                            onClick={() => this.deleteTableElement(props.row)}
                            className="material-icons"
                            style={{ color: "red", cursor: "pointer" }}
                        >
                            delete
                        </i>
                    </div>
                );
            },
        });
        return columns;
    };

In this case, I want to modify the item. The react table is not updating.

Upvotes: 6

Views: 32399

Answers (3)

Reinaldo Pastran
Reinaldo Pastran

Reputation: 81

thanks to @Adam and @MichaelRovinsky , theres the result and my problems are fixed with the function slice, the component state should be update with a copy

let data = this.state.list.data;
        data.splice(row.id, 1);
        const copy = data.slice();
        this.setState({
            list: {
                ...this.state.list,
                data: copy,
            },
        });

Upvotes: 0

Michael Rovinsky
Michael Rovinsky

Reputation: 7210

Here is a simple example of a table with deletable rows.

Pass your initial rows to the component as a prop and copy them to the state.

On click delete button, make a copy or rows without deleted row and update the state. The table will re-render.

const {useState} = React;

const MyTable = ({rows, columns}) => {
  const [data, setData] = useState(rows); // Copy rows to the state
  
  const deleteRow = index => {
    // Create a copy of row data without the current row
    const newData = [...data.slice(0, index), ...data.slice(index + 1)];
    // Update state
    setData(newData);
  }

  return (
    <table cellSpacing="0" cellPadding="10">
    <thead>
      <tr>
        {columns.map(column => (<th key={column}>{column}</th>))}
        <th/>
      </tr>
    </thead>
    <tbody>
      {data.map((row, index) => (
        <tr key={index}>
          <td>{row.text}</td>
          <td>{row.value}</td>
          <td>
            <button onClick={() => deleteRow(index)}>Delete Me !</button>
          </td>
        </tr>
      ))}
    </tbody>  
    </table>
    )
}

const tableRows = [
  {
    text: 'A',
    value: 100,
  },
  {
    text: 'B',
    value: 200,
  },
  {
    text: 'C',
    value: 300,
  },
  {
    text: 'D',
    value: 400,
  },
];

const tableColumns = ['Text', 'Count'];


ReactDOM.render(
  <MyTable rows={tableRows} columns={tableColumns} />,
  document.getElementById('container')
);
th, td {
  border: 1px solid gray; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

<div id="container">
</div>

Upvotes: 3

Adam Jenkins
Adam Jenkins

Reputation: 55613

Whenever your component unexpectedly doesn't update, it's because you're mutating state. Literally 100% of the time:

        let data = this.state.list.data;
        data.splice(row.id, 1); // <- splice mutates an array, mutating state is bad
        this.setState({
            list:{
                ...this.state.list,
                data:data
            }
        })

should be:

        this.setState({
            list:{
                ...this.state.list,
                data:data.filter((d,i) => i !== row.id)
            }
        })

Upvotes: 12

Related Questions