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
Indonesian
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
So I hope I could explain
the problem set we're dealing with here
in the last lecture
and it's not uncommon problem set
that you have a backend
which might not be doing
all the work you want it to do it
and therefore we'll now have
to find a way around that problem.
As I mentioned
we can send our HTTP request here
in the reducer
but that of course then means
that we need to find a different way
and here these two main options
where we can run our async code
become important again.
We can run it into component
or in an action creator.
Now as mentioned,
let's start with the component
and here it's the product item
where we have this
add to cart handler,
where we send a request.
Now, what we can do here
is we can also use useselector
from react redux
and get our current cart
before it's updated
then do all that transformation
which we do in the reducer
ends out of product item
without mutating the state though,
that's important.
We'll need to take care
that we don't do that there
and then we send the request
and here's how that code
could look like.
I did not write this code
together with you
because this will not be
the final code we'll use
because it has problems.
You will find it attached though
you'll find this code snapshot attached
so that you can also
run it in your own project.
What did I do?
I worked on add to cart handler
in the product item
and I, first of all used
useselector from react redux
to select my cart from there,
the entire cart.
So this cart stayed object
with items and total quantity
and then in add to cart handler,
I create my own new total quantity.
I don't change it in the existing state
because we must not
mutate the state here
and that's important.
We can write this mutating code here
inside off the reducer function
in our slice
because Redux toolkit
has this internal transformation
for changing our code
such that it doesn't mutate the state
but that only applies
inside of those reducer methods.
In product item
so in a regular component,
that's not the case
and if here I would set
cart total quantity
equal to cart total quantity plus one
then I would change
a JavaScript object in memory
which is all the part of the Redux store
without making Redux aware of it
because I would be changing it
outside of a reducer function,
which is horrible
which you must avoid.
So that line,
which I selected here
would be super bad code.
You must never mutate Redux state
and especially don't do it
outside of a reducer.
That's why instead
I create a new constant
which has the updated quantity
without changing the quantity
in the Redux store yet
and then I do similar things
for updating my items.
I create an updated items constant
where I copied the items in the cart
with the slice method
that creates a brand new array
with the existing objects
but a new array.
Then I get hold of the existing item
by identifying it in my copied items.
That item, however,
will still be an object in memory
which is part of the Redux store
because objects
are reference values in JavaScript.
So I copy that object
into a new object as well.
So that updated item
is a brand new object in memory
and then I can update properties
off that object
without manipulating my Redux store.
If I would be updating existing item,
I would be manipulating my Redux store
not if I create a copy first though
and then I find the index
of that existing item
and I replace the current item
in my cart with the updated item
or if we didn't have the item
as part of the cart before
I push a brand new object
to my updated items array
and then I'd arrive my new cart
by creating a new object
where I said total quantity
to that new total quantity up there
and where I said
items equal to my updated items
and then I dispatch a new action
because I added
a new reducer in the store,
the replace cart reducer.
I added that off screen
and that simply
gets the new total quantity
and the new items
from the payload and overrides it
in the Redux store
and therefore the payload
which I dispatch is an object
with a total quantity
and an items key
and that's what I create here
and what I then dispatch here
and I'm not sending
a HTTP request yet by the way
if I save that with the old action
which we dispatched here,
I commented out,
if I go back to my application
and I reload
I can still add items
to the cart as before
and it works as before.
Now I did not change the logic
that runs when I click the plus
and minus buttons.
Now what's the problem
with this approach though?
The problem is,
that if we would use this
in all the parts of our application,
where we need to update the cart.
So if we would also use it
instead of cart item to be precise
then we would need to copy
all that logic here
which I added to this component
to the cart item component as well
or we outsource it into an extra file
which exports a function,
which does this, maybe.
So then we don't have
to code duplication
but still we'll have another problem.
We do the data transformation
in some helper function
and in the end directly
in our components
we don't do the transformation
in our reducers.
We would be able to get rid of
add item to cart
if we used this replace cart approach
in all the places in the application
and that means
that our redux reducers
wouldn't do a lot of work.
They'd just get some data
and store it.
That can be fine
and if that's your personal preference
that's not necessarily bad
but it's not the main idea
behind using Redux
because when it comes to the question
of where to put our code,
we often have the choice
between fat reducers, fat components
or fat actions.
So when we consider
where to put our logic, our code
then we have to differentiate
between synchronous,
side-effect free code
and code with side effects
or codes that is asynchronous
and that code,
which I provided to you in product item
at the moment is side effect free
we're not sending
that HTTP request yet
deliberately because I wanna focus
on this other problem
we're currently talking about.
All this code here
just transforms data.
It's asynchronous code
and side effect free.
Now in such a case
if we're dealing with synchronous
side-effect free code.
So if we basically
just have some data transformation
so we're on the left side
of the slide
then you typically
should prefer reducers.
Now, if you personally
have a different opinion
if you like having your code
in the component
that of course is fine
but generally it is considered
a bit better to prefer reducers
and a wide action creators
or components for that.
Now we still haven't had
a closer look at action creators.
We will soon
but we did definitely work a lot
with components
and you wanna avoid putting
your data transformation code there
when working with Redux.
It would be different
for asynchronous code
or code with side effects.
There you should prefer
action creators or components
and you absolutely
must never use reducers.
So therefore at the moment
we have a problem.
We have sub optimal code
because we are performing
the data transformation
in the component
and not inside of the reducer
if we rely on replace cart
and that is sub optimal
that's the reason why
we didn't write this code together
because I don't wanna keep that code here
but what would be
a better way of doing it then?
Because we need to prepare it
before we send it to Firebase
because we can send the request
from inside the reducer.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.