Search code examples
reactjsfiltersetstate

React - remove nested array item using setState function call


I am trying to remove a (semi) deeply nested item from an array using setState but it doesn't seem to be working. My state is structured as follows:

state = {
  currentSeries: null,
  currentRowIndex: null,
  rows: [
    {
      id: shortid.generate(),
      nodes: [], 
      series: [], // array with item I want to remove
    },
  ],
};

and my remove item call:

onRemoveModelElementClick = (rowId, modelElementId) => {
  this.setState((prevState) => {
    const index = prevState.rows.findIndex(x => x.id === rowId);
    const series = prevState.rows[index].series.filter(s => s.id !== modelElementId);
    return series;
  });
};

I tried spreading the remaining state is several ways but it does not seem to update properly. I the rowId and modelElementId are correct and I can verify they do filter the correct item out. I am just having trouble on what to return. I know it is something simple but for the life of me I can't see it.


Solution

  • My recommendation would be to use .map to make things are bit easier to digest. You can then write it like so:

    onRemoveModelElementClick = (rowId, modelElementId) => {
      const updatedRowsState = this.state.rows.map(row => {
        // this is not the row you're looking for so return the original row
        if (row.id !== rowId) {
          return row;
        }
    
        const filteredSeries = row.series.filter(s => s.id !== modelElementId);
        return {
          // spread properties (id, node, series)
          ...row,
          // overwrite series with item filtered out
          series: filteredSeries,
        };
      });
    
      // since rest of the state doesn't change, we only need to update rows property
      this.setState('rows', updatedRowsState);
    }
    

    Hope this helps and let me know if you have any questions.