Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

301
Views
How can I delete an item from list without re-rendering undeleted Items?

Thank you for all your comments and helpful remarks. following your advices, please find below a code sandbox link

https://codesandbox.io/s/magical-butterfly-uk0fjq?file=/src/item.js

which may help you figure out the issue. Everything is obvious in the console, with multiple logs, which, given the current scale of the example, does not pose any performance issue, but which could if there were a long list of items.

So the question is, how to proceed for preventing items which are not deleted from re-rendering, in spite of the fact that the parent (ItemList) re-renders.

The console shows the Item rendering.

As stated previously, I have used a useMemo + useCallback combination, but the result proved to be unstable.

Hope this example will help and be more explicit.

EDIT

regarding the console log, strangely, the sandbox example logs 2 times App, 2 times ItemList and 12 times Item, whereas on the computer it logs only 1-1-6 times

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

So, if you want to minimize the re-renders of the items, you need to make sure of a few things

Memoize the component

You can use React.memo on the component you want, which will prevent re-renders when the props/state do not change.

so, use

export default React.memo(Item);

instead of

export default Item;

Make sure the props are the same

When you render the Item component you pass deleteItem as a prop with a value that is received from the App component. However, this function is not a stable (it is redefined each time the App component renders. And since the App holds the items state, it will rerender after each deletion. This will trigger a new deleteItem to be defined, and that will cause the Item to re-render.

To make this stable, you need two things.

  1. to use React.useCallback which re-uses the same function when its dependencies remain the same.
  2. use the function form of the setItems

so, instead of

const deleteItem = (newItem) => {
  const newItemList = items.filter(
    (item) => item.reference !== newItem.reference
  );
  setItems(newItemList);
};

use

const deleteItem = React.useCallback((itemToDelete) => {
  setItems((currentItems) =>
    currentItems.filter((item) => item.reference !== itemToDelete.reference)
  );
}, []);

You also have an issue in your code, where you .map the data but then before returning each Item you push it in an array and return that instead. Just return the <Item ..>

So instead of

    {props.data.map((item, index) => {
      const newList = [];
      newList.push(
        <Item
          deleteItem={props.deleteItem}
          key={item.reference}
          item={item}
        ></Item>
      );
      return newList;
    })}

do

    {props.data.map((item, index) => {
      return (
        <Item
          deleteItem={props.deleteItem}
          key={item.reference}
          item={item}
        ></Item>
      );
    })}

Updated codesandbox with all changes: https://codesandbox.io/s/twilight-water-9iyobx

about 4 years ago · Juan Pablo Isaza Report

0

It sounds like you want to iterate over your array of objects to produce rows of data in a table with the last cell in each row to be a "remove" button that removes the row. And you can do that. No need for useEffect.

const { useState } = React;

// Pass in the data
function Example({ data }) {

  // Set the state with the data
  const [ tableData, setTableData ] = useState(data);

  // When a remove button is clicked `filter`
  // out those rows that don't match the row id
  // and reset the state
  function handleRemove(e) {
    const { id } = e.target.closest('tr').dataset;
    const filtered = tableData.filter(obj => {
      return obj.name !== id;
    });
    setTableData(filtered);
  }

  // Create some rows by mapping over the
  // table data
  return (
    <table>
      {tableData.map(row => {
        return (
          <Row
            key={row.name}
            row={row}
            handleRemove={handleRemove}
          />
        );
      })}
    </table>
  );

}

// Create a table row and populate the cells
// with the information from the row object
function Row({ row, handleRemove }) {
  return (
    <tr data-id={row.name}>
      <td>{row.name}</td>
      <td>{row.reference}</td>
      <td>{row.description}</td>
      <td>
        <button
          onClick={handleRemove}
        >Remove
        </button>
      </td>
    </tr>
  );
}

const data = [
 {name: "NAME 1", reference: "REF 1", description: "LOREM IPSUM"},
 {name: "NAME 2", reference: "REF 2", description: "LOREM IPSUM"},
 {name: "NAME 3", reference: "REF 3", description: "LOREM IPSUM"},
 {name: "NAME 4", reference: "REF 4", description: "LOREM IPSUM"},
 {name: "NAME 5", reference: "REF 5", description: "LOREM IPSUM"}
];

ReactDOM.render(
  <Example data={data} />,
  document.getElementById('react')
);
table { border-collapse: collapse; border: 1px solid #565656; }
td { border: 1px solid #dfdfdf; padding: 0.5em;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

about 4 years ago · Juan Pablo Isaza Report

0

When updating the state you need to spread the previous state first before you update it Example:

const deleteItem = (newItem) => {
  const newItemList = items.filter(item => item.reference !== newItem.reference);
  setItems(prev => (...prev, newItemList));
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!