简体   繁体   中英

How to remove one item from cart?

I don't quite understand this function, like what do you filter out and the way it work...can anybody help me to expalin this? I'm a begginer and i need your help! Thank you so much btw!

Function:

removeFromCart =(product) => {
  const cartItems = this.state.cartItems.slice()
  this.setState({
    cartItems: cartItems.filter((x)=>x.id!==product.id)
  })
}

Array.prototype.filter expects a callback that returns a boolean.

If the callback returns true , the element gets pushed to the new array and if it returns false, the element will not be pushed.

const cartItems = this.state.cartItems.slice() creates a new array and can be removed as filter creates a new array anyway.


cartItems.filter((x)=>x.id!==product.id)

If we consider the above snippet, the returned value is x.id!==product.id because if the id matches, x.id !== product.id will evaluate to false and returning false will remove the product.


Update:

You also seem to have an issue with passing the product to the function. Fixed that and here's the updated sandbox:

编辑 redux 购物车(分叉)

<button className="button" onClick={() => props.removeFromCart(item)}>
  Remove
</button>

This is the longer version of that code, you might get confused because your version has a lot of shortcuts and bad variable name. (comments)

removeFromCart = (product) => {
  const cartItems = this.state.cartItems.filter((item) => {
     return item.id !== product.id;
  });


  this.setState({
    cartItems: t
  })
}

let's know this:

const cartItems = this.state.cartItems.slice()

First, you don't need this one as filter already returns a new array usually you use slice to create a copy (portion) of that array (usually we pass arguments on it and I've rarely seen a usage where the dev uses it as a "clone" function. You can read more about it here .

  const cartItems = this.state.cartItems.filter((item) => {
     return item.id !== product.id;
  });

for this one, I renamed your variable x into item to make it more understandable. Since cartItems is an array, this function will go through each items then create a new array where the item id is not the same as product id ( return item.id !== product.id ). Read more about filters here

  this.setState({
    cartItems
  })

you pass the newly created cartItems to update your state.

In you code the Array.prototype.slice function is use to create a copy of the state cartItems which is an array. the Array.prototype.filter function is use to filter the array and return only item which match the condition which is test in the callback function passed to the filter function.

Precisely you are setting the cartItems array to be equal to an array which contains only item which id is different than the id of the product pass as argument of the removeFromCart function.

There are two things to note.

  1. First of all, we are taking a shallow copy of the array by using slice() method of javascript. This is done so that

we do not mutate the original state

(Which is a foundational principle in React)

const cartItems = this.state.cartItems.slice(); // We have the copy of original state 

The same can we achieved with ES6 spread operator though (which is recommended in React)

const cartItems = [...this.state.cartItems];// This does the same what slice() does
  1. Second part is the logic in filter method which is a Higher Order Function.

     cartItems.filter((x)=>x.id!==product.id)

For each item in your array (Which is each object in your array), this callback function runs

(x)=>x.id!==product.id

in each iteration and checks whether item.id (ie Current Object's id) is not equal to the Id selected. So, All the items are filtered and shown expect for the item where product's id matches the item's id (This one is not shown in DOM) all other.

Finally, you are updating your state with the filtered items and hence your functionality works as expected :)

Would recommend you to learn about Higher Order Functions, such as map() , filter() , reduce() since they are used a lot in React and Javascript frameworks, since you are a just starting.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

In your Cart.js , you have to change call function and pass item, props.removeFromCart(item)}

<button
  className="button"
  onClick={() => props.removeFromCart(item)}
>
  Remove
</button>

and in App.js , keep same or,

  removeFromCart = (product) => {
    //const cartItems = this.state.cartItems.slice();
    this.setState((prevState) => ({
       cartItems: prevState.cartItems.filter((x) => x._id !== product._id)
    }));
  };

this do exactly what needs to be done, but it removes selected cart elements

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM