Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Now, when we remove items from the cart
we wanna get a State and Action,
because again we'll get some extra payload that helps us
identify the item that should be removed.
And here I expect that my payload is just the idea
of the item.
I can expect this
because I am the one writing this code here.
And with that, we now wanna find that item
and remove it from the array.
Now, we don't need to check if it's part of the array
we know that it will be part
but we need to find out how many items are in the array.
So for this again, I'll get my existing item
by reaching out to state.items
and finding the item where the item.id === id
I'm getting as a payload.
And then we wanna check
if existingItem.quantity===1
If it's one, then we wanna remove the item
from the array entirely.
If it's greater than one,
we just wanna reduce the quantity by one.
So, the else case is simpler.
In the else case that we have more than one item,
we just reach out to the quantity and decrease it by one.
But if the quantity is one,
we wanna remove the item from the array.
And we can do this by
setting state.items = state.items.filter
and then filter out that one item that we wanna remove.
That overwrites the array of items
with a new array where this item
which we wanna remove will be missing.
And it will it be missing because we filter
40 item where the item.id !== id.
So, we keep all the items,
where the ids do not match the one id
we're trying to remove.
And therefore for 40 item where the id is equal,
we'll filter that out and remove it therefore.
That's how we can update these items
to remove the one item that should be removed
from the array whilst keeping all the other items.
And that logic should work.
I guess we're going to see it once we tested
but it does look good to me.
Now, here's a quick note from Max from the future.
I forgot one important step here, which you should add
and which I will add later in this module
but which is missing at the moment.
When we remove item from the cart
and the item is still part of the cart,
so the quantity, wasn't one
then just updating the quantity as I'm doing it here,
is not enough.
We also should update the total price of that item.
And we do a sell by adding existingItem.totalPrice
and setting that equal
to existingItem.totalPrice - exsistingItem.price.
So, deducting the price of a single unit
from the total price since we are removing one unit.
That's a line of code you should add here.
I have not edited here,
again, I will add it later in this module
because I overlooked it here,
I'm just showing it to you right now
because of course you should have that extra line in there.
Now I'll store this Slice in another constant,
the cartSlice and of course we'll export it here.
We'll export it as a file default,
and we will also export the actions
because of course we will need to dispatch those actions.
So, I export a named.
Export here I add a named export,
exporting a constant which I'll name cartActions
where I access cartSlice.actions.
Now in index.JS,
I wanna merge this new Slice into my overall Redux store.
So, I'll import cartSlice from ./carte-slice
and add this as a number of reducer in my reducer map.
Maybe we use cart as a key here
and then here point at cartSlice.reducer, okay.
With that, we added this as well.
Now, let's wire it up.
and for wiring it up, I actually need real products.
In Products.js, I have a hard coded product here,
and that makes no sense.
This should be generated dynamically
so that we have real product data with which we can work.
Now we could manage our products with Redux as well
that might be a nice practice,
setting up another Slice for products,
but since we don't do anything with the products
since we don't add or delete products,
I'll instead just add a DUMMY PRODUCT array here
in the products component, which is an array.
And I'll set up my DUMMY PRODUCT data there.
Now every product should have an id,
because in the cartSlice, we are working with that id here
and we should therefore also have a price and a title then.
And hence here, I'll add an id.
Let's say an id of p1 and a price of six
and title of 'My First Book'
and then also a description
because we need that down there
for outputting the product item.
So, I'll add a description of 'The first book I ever wrote.'
It's just some dummy data
so I'm not spending too much time
on preparing the best possible data here.
Now, I will add another product with an id: p2
and a price of five, which is 'My Second Book.'
I'm super inspired, as you can tell.
So, that's the second book,
'The second book I ever wrote,'
and now we've got some dummy data.
Now I wanna use that dummy data
to dynamically rendered these product items.
So, here in add-on add list,
I'll map all those DUMMY PRODUCTS into product items.
So, I'll paste that in there
and set title= product.title,
set the price=product.price and you guessed it,
sets the description=product.description.
And since we're mapping give every product item
a key of product.id to help React.
So, now we got the product data
we can now work with that data,
and I wanna start instead of the product item,
there I have the Add to Cart button.
And we wanna wire this button up to this function
to the addItemToCart function in our cartSlice.
So, in ProductItem I will add new function here,
addToCartHandler where I wanna dispatch
the appropriate action.
Now of course, we still dispatch actions as we learned it,
so we import useDispatch from react-redux to get access
to this dispatch function
by then executing useDispatch in the ProductItem.
And then here in addToCartHandler, I called dispatch
and now we need to get access to the cartActions.
So, I will import cartActions from going up,
going up store/cart-slice,
and then here dispatch cartActions.addItemToCart.
Now we again execute this action creator function
but now we also need to pass data to it,
because we now want to pass that product
which should be added to that addItemToCart function.
We are expecting it there.
Now there, we need to work with the id
and price and we need to title,
so we should make sure that we send all that data.
Now in ProductItem, I do have the title and the price,
but not the id.
So, I will always expect the id as a prop now,
and in Products.js, I will forward the id like this.
So that we have it available inside of ProductItem
and therefore, inside of ProductItem
when we add an item to the cart here,
I pass an object as a payload to this action.
And this object has an id field
which points at this id, which we're extracting from props.
And we can therefore always use the shortcut
and do the same for title and for price.
So, that this is the object we are dispatching.
And again, I'm using that modern JavaScript shortcut here,
where when the key name and the variable name
holding the value are equal,
we can omit the right side of the property assignment
and just write down those property names
and it's automatically expanded behind the scenes.
So, we can just write it like this.
This will now dispatch all the data we need to dispatch,
and therefore we can now connect addToCartHandler
to our button.
So, here we add onClick
and then point at the addToCartHandler.
If we do this and I reload that should work,
but we can't tell because we're not really updating the cart
and we're not updating the batch here either.
So, let's maybe start with the batch
and for this let's again go to the CartButton component.
There we already dispatch,
now we also need data from the cart.
We need to totalQuantity.
And speaking of that, I just remembered
that I forgot to update the totalQuantity.
When we add an item to the cart,
we don't just wanna update the existing item
or the items array to be precise,
we also wanna update the totalQuantity field.
and therefore, we can simply say
that no matter if we have an existing item or not,
the totalQuantity will simply increase by one.
We have one more item in the cart that is safe.
And the same is true for removeItemFromCart.
No matter if we have that item
in the cart once or multiple times,
we definitely wanna reduce the totalQuantity by one.
So, we should add this code to removeItemFromCart.
And with that, back in the CartButton,
we can now read data from the state
by also importing useSelector
and then selecting a piece of data.
So, we call useSelector,
past is function for selecting data from the state
and dive into state.cart,
dot cart because in index.js here,
we gave this a cart key
and then into the properties
we set up in the state of our cartSlice.
So, in this case, we're interested in the totalQuantity,
hence here we dive into state.card.totalQuantity
and store this in, let's say CartQuantity constant.
And now it's that CartQuantity constant,
which will output down there.
With all that done, if we now save this,
if I reload, if I add items to the cart,
that badge on the top, right corner updates.
Now let's make sure we rendered this cart correctly.
And for that, we need to go to the Cart.js file.
There, I have this list of CartItems
and at the moment it's hard-coded.
So again, here, we wanna use Redux instead
and to tap into our Redux managed cart state.
So, since we need data from Redux,
we need to import useSelector
and import that from react-redux,
and then here call useSelector and access state.cart
and then there dive into our items,
because we want those CartItems like this,
and then we can output them here.
We can map our CartItems,
into cart item components
and here that CartItem expects the item prop
which holds the object of this shape.
And the good thing is that in cartSlice.
We already are setting up CartItems
with a certain structure where we do have a price,
and a quantity and a total price and so on.
And therefore we now just need to translate
those properties, which we have in our Redux store
and our Redux state to the properties expected here.
So, we create an item on the fly
which we pass as item to CartItem
and the title should be item.title here.
The quantity should be item.quantity
since in the Redux state
I am using quantity as a key as well,
but I'm not using title as I just see I'm using name.
So, in Carts.js here, we should reference item.name,
since item is the data coming from Redux.
Now the total price will be item dot, let's have a look,
total price.
So, we wanna access item.totalPrice
and the single item, price is item.price.
So, that's now the item which we pass
into CartItem for every item we're getting from Redux here.
Let's see if that works.
If we saved this.
Yeah, I can reload.
Let's see.
I got multiple items here, so that doesn't seem to work.
It doesn't seem to get that we have an existing item.
And I think I know why.
If we have a look at cartSlice,
I'm getting an existing item by comparing the idea
of the stored item to the newItem.id.
The problem with that is that I'm storing the item.id
in the item.id field here.
So, we should just change this to just Id here
so that when we extract the id, we are successful.
And if we do that and reload
if I now add the same item multiple times,
it is grouped together.
So now, this is working
and we have to add a second item to have a second entry.
And then that is also grouped together
if we add more and more items.
So, that's working.
We also showed go to Carts.js
and make sure that when we create multiple CartItems here,
we do add that key again and point at item.id
as a unique identifier.
That has nothing to do with Redux,
but helps React as you learned earlier in the course.
So now we got that,
let's now make sure the minus
and plus buttons in our CartItems work.
And for this, we need to dive into the CartItem
and dispatch actions when they are clicked.
So, you know how that works.
We import useDispatch from react-redux
and we need our cartActions.
So, I'll import cartActions from going up, going up
store/cart-slice.
And then here in CartItem we call useDispatch to get access
to that dispatch function,
and we then add new functions
which will be wired up to these buttons.
Let's say to removeItemHandler,
and then also the addItemHandler.
Now, let's start with the removeItemHandler,
and let's dispatch that remove action.
For this, we need cartActions.removeItemFromCart
and that action wants a payload,
it wants the id as a payload.
So, we should make sure that this is passed on.
And for this, we need to accept the id as a prop
in CartItem and then Cart.js again,
make sure that we pass it as a prop.
So actually here in this item object, which we're creating
I'll add the id field and use item.id.
And now instead of CartItem,
we get this id here and we can now pass this
as a payload to the removeItemFromCart action.
Now, for adding an item, we wanna dispatch cartActions
addItemToCart and execute that.
And here we again, need to pass in that object
which addItemToCart expects this object
which should have an id and a price and a title field.
So back in CartItem, this object will get an id field
with this id.
It will get a title field with that title
and also the price field with that price, like this.
Now we just need to wire up these functions to our buttons.
So, on the first button, the minus button
I'll connect the removeItemHandler to onClick
and on the second button it's the addItemHandler.
And with that if we saved this,
if I now reload again, I can add items,
toggle my cart and add the multiple times.
Also add them with this plus button
and all the remove them with the minus.
And if only one item is left
and I click minus it's removed entirely.
So, this is now working and that's again Redux and Action.
It's nothing new.
It's only what we learned thus far
but therefore it's of course a great practice.
But now in the next lecture, let's add some async code
and let's see how we can deal with that
when working with Redux.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.