heathrow
heathrow

Reputation: 103

Why is my original state mutated when filtering with react redux

im using redux in an react app. Why is this filtering func mutating the original state.products? I cant understand why

state.products = [
   { 
      type: "one",
      products: [
         { active: true },
         { active: false }
     ]
  }
 ]

function mapStateToProps(state) {
 const test = state.products.filter((item) => {
   if(item.type === "one") {
     return item.products = item.products.filter((item) => {
       item.active
      });
    }
    return item;
  });

  return {
    machineSearchWeightRange: state.machineSearchWeightRange,
    filteredItems: test //This will have only products active
 };
}

filteredItems will have only products that is active but the state.products is also updated containing only active products when trying to filter on the same data again.

Suggestions

Upvotes: 1

Views: 120

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074276

Because you're assigning to a property on an existing state item:

function mapStateToProps(state) {
  const test = state.products.filter((item) => {
    if(item.type === "one") {
      return item.products = item.products.filter((item) => { // <========== Here
        item.active
       });
     }
     return item;
   });

   return {
     machineSearchWeightRange: state.machineSearchWeightRange,
     filteredItems: test //This will have only products active
  };
}

Instead, create a new item to return. Also, it looks like you need map along with filter, and you're not actually returning item.active in your inner filter (see this question's answers for more there):

function mapStateToProps(state) {
  const test = state.products.filter(({type}) => type === "one").map(item => {
    return {
        ...item,
        products: item.products.filter((item) => {
          return item.active;
        })
    };
  });

  return {
    machineSearchWeightRange: state.machineSearchWeightRange,
    filteredItems: test //This will have only products active
  };
}

Side note: This:

products: item.products.filter((item) => {
  return item.active;
})

can be simply:

products: item.products.filter(({active}) => active)

Upvotes: 5

Related Questions