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
Now before we start fetching data,
let's have a look at the alternative,
of putting all that side effect logic
into our component.
That is perfectly fine,
but we learned that it's only one
of the two options.
The other option would be the usage
of an action creator.
And that's something we haven't done up
to this point.
Or actually we kind of did.
We are using action creators all the time.
Something like this here,
is an action creator.
We get those action creators automatically
by Redux toolkit.
And we call them,
to create the action objects which we dispatch.
So these are these automatically created action creators.
Now we can also write our own action creators
and we can write them
to create so-called thunks.
Now what is a thunk?
And why might we want to do that?
A thunk is simply a function,
that delays an action until later,
until something else finished.
And we could write an action creator as a thunk,
to write an action creator,
which does not immediately return the action object,
but which instead,
returns another function
which eventually returns the action.
So that we can run some other code
before we then dispatch the actual action object
that we did want to create.
This might sound cryptic,
but that's a very common pattern
and it is easy to implement.
So let me show you how it would work.
And let's dive into these custom action creators,
into these action creator thunks
by moving that code
for sending carts data,
out of the component,
though it would be fine there,
but to show the alternative,
let's move it out of there,
and let's move it into an action creator.
Now for this, I'll go to cart slice,
because I wanna write this custom action creator
in that same file,
because that is my file
for managing the cart.
Now to create our own action creator,
we can go to the end
of that file,
after this slice, that's important.
So outside of this slice object,
and there we can create a new function.
Let's maybe name it, send carts data.
Now that is a regular function,
and therefore, of course,
as always you could create it
with the function keyword as well.
And here let's say we expect the carts data.
Now we could write this
as a action creator,
by now returning an action object in here.
So object with a type of, whatever,
and maybe some payload.
We never did this ourselves,
because Redux toolkit,
creates these action creators automatically for us,
for all those reducer methods.
Every method in the reducers object,
receives such an action creator,
which is called,
by using that reducer function name.
That's what's inside
of these actions here.
So we don't need to write,
such simple action creators on our own.
But we could create,
action creator which does not return,
such a action object here,
but which instead returns another function.
And of course in JavaScript,
you can write functions
that return other functions.
Now that would be a function
that should receive the dispatch function
as a argument.
And we'll see where this is coming
from in a second.
And where inside of this function,
we can then therefore, dispatch,
the actual action we wanna perform.
Like for example,
showing a notification
or adding a cart item,
but before we call dispatch,
we can of course do other things,
before we call dispatch,
we can perform any asynchronous code,
any side effects,
because we will not yet,
have reached our reducer.
We're not running this code in a reducer.
It's a separate standalone JavaScript function instead.
So in our case here,
we could go to app JS,
and actually grabbed this dispatch action,
where we dispatch,
show notification, copy it,
go to the cart slice,
and execute this in here.
If were this need to get access
to the UI actions,
so I will import them,
I'll import UI actions
from UI slice, from that folder.
If we do that,
we can dispatch this action from in here.
We can then also, copy all that,
code here for sending the request
and handling the response.
And I'll not just copy it.
I'll cut it.
And I'll remove this, dispatch code
because we all did copy
to that already.
So now here we can execute this down here,
after dispatching that first notification.
Now I'm using await here.
And the great thing is,
we can convert this into async function,
this function which we returned here,
that is fine.
Now here we need the cart,
here I called it carts data.
Let me name,
let me call it card here as well,
as a parameter.
So that we do get that card
that should be sent.
Now in app JS,
we can now also grab the Abra code,
like dispatching, this action here,
go to cart slice and dispatch.
That if we make it past this, if check,
and now when it comes
to handling the potential errors,
I will actually create a new function,
send request here,
which is async,
and put my code
or sending the response
and handling the response
for sending the request
and handling the response,
inside of this function,
so that I can,
call, send request here,
and await that as well,
because it's a async function.
It returns a promise.
And since we're still inside
of this outer function,
where we also use async,
we can use await here as well.
And I know that it's quite some nesting of functions,
but this extra nesting here is required
because of how to fetch API works.
Because now we can,
wrap, try catch around this,
await block here,
and catch any errors
that might be frozen from in,
from anywhere inside of this function.
And then dispatch our error
and notification as well.
So here all, first of all,
dispatch, success ends out
of the try block if this succeeds,
but if we make it
into this catch block instead,
I wanna dispatch,
this error case instead.
So we'll copy that
into this catch block.
So with that what we're doing,
is we're creating a function,
send carts data,
which immediately, without doing anything else,
returns another function,
a async function.
We don't know yet who will execute that function,
but we will soon to know it.
But in that function,
we then dispatch a notification, action.
Then we create a new function,
so yet a never nested function,
which we create on the fly,
which has also async,
in there we send the request.
This function is then called by us,
instead of try-catch,
simply to handle any errors.
If we don't have an error,
we dispatch the success notification.
If we do have an error,
we dispatch the error notification.
So now we created this sent carts data function.
How do we now call
that function and where.
We could of course call it
from inside a component,
but that's not the idea.
Instead in app JS in there,
I will clean up the content
and use effect.
I'll keep, you could use effect though
but I'll clean up all the code in there,
and I'll get rid
of my UI actions import.
I actually will keep that,
is initial code though,
where I return
and set his initial to false.
I'll keep that.
But other than that,
I cleaned this up,
because now I wanna do something
which might look weird at first.
I wanna use sent carts data
as a action creator.
So in app JS, I still wanna dispatch,
after this initial check,
and I wanna dispatch,
this send carts data,
action so to say.
Therefore I'll export it in cart slice,
and then app JS hold an import.
I'll import, send cart data
so that function which we just exported,
from store cart slice,
from that file.
And then here use effect,
I dispatch sent cart data,
and I'll execute it
and pass my cart as an argument.
Now this might look weird.
What we dispatched before,
always were action creators.
So functions that return an action object
with a type and so on.
Now in cart slice,
we are instead dispatching a function
that returns another function.
But the great thing about Redux,
when using Redux toolkit,
is that it's prepared for that.
It does not just accept action objects
with a type property.
Instead it also does accept,
action creators that return functions.
And if it sees,
that you're dispatching,
a action which is actually a function,
instead of action object,
it will execute
that function for you.
So Redux will execute
that function for you.
And with that function,
I mean this function here,
it will give us
that dispatch argument automatically.
So that in that executed function,
we can dispatch again,
because there's a such a common pattern
that we wanna have action creators
that can perform side effects.
And that can then dispatch Abra actions,
which eventually reached the reducers,
as part of a flow off side-effects,
or as a flow of steps
that should be taken.
And that's what we have here.
So we can use a function
that returns another function,
as a action as well.
That is built into Redux
when using Redux toolkit.
So this patching this here will work.
And when we dispatch,
Redux will go ahead,
and it will execute this function for us.
And therefore all our other actions will be dispatched,
and the HTTP request will be sent.
So if you save all of that,
if we reload here,
if I add something to my cart,
it works just as before,
that still works and firebase,
the staff were still being hit,
and all the data,
is still being stored in there.
That still works,
because that is a support
that pattern by Redux.
And why would we wanna use that pattern?
Well, it's simply an alternative
to having that logic in your component.
You can add that logic in your components.
You can stick to the approach we had before,
but it's also not a bad idea
to keep your components lean,
to not have too much logic in them.
And at the moment,
by moving that logic
to this action creator function,
we did achieve this.
This component is now leaner.
It only dispatches one action,
not multiple actions.
It doesn't care
about sending the HTTP request,
and all the hard work,
happens inside of our custom action creator function,
in our Redux files.
And splitting our recode like this,
could be considered good,
because it keeps our components lean.
That does not mean
that the other approach is bad.
Both options are viable
and that's why I am showing both here.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.