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 we did now translate our Redux-only,
non-React example
where we also use the counter
to this React application
so that there we also manage this counter state with Redux.
And we actually do more than what we did initially
in this module when we just got started with Redux.
Now, in this starting project,
which I provided to you,
we got a couple of other components as well,
not just a counter.
We get a couple of other components as well
because there's more I wanna practice
and teach you when it comes to Redux.
And therefore, it's now time
to use some of these other components.
In the App.js file, in this App component,
let's now return more than just the counter.
Let's add a fragment imported from React.
This built-in Fragment component
so that we can have a couple of adjacent JSX element
and let's also add our Header component here.
And for this, we need
to import Header from ./components/Header.
And let's also add the Auth component here.
And for this import Auth from ./components/Auth.
Now, if we do that,
we have this little demo application.
We still have the counter down there
and we could also remove it,
it's not related to this mini demo at all.
But I will leave it there
so that we still have the Redux state
for the counter and now we're also going to add state
for this demo application but which state?
Well, here I would like to make this login form work.
Not really, we won't really add authentication here.
We do this in a separate course section
because there's more to it than a little bit of Redux usage
but I wanna make sure that when we click Login,
we do switch into some login mode
and for example, what we see here
in the navigation bar changes.
These items and the logout button
should only be displayed if we are logged in in Redux
and I also wanna swap this login field here,
this login form for another component,
the UserProfile component which has some dummy output.
So we have a brand new state to manage.
And unlike the counter state,
which was just a basic example,
the authentication state
and the answer to the question
whether the user is logged in or not
is indeed not just local state,
which matters to one specific component
but it is application-wide state,
which matters to a lot of components in the application.
It matters to the Header,
it matters to the Auth component,
it matters to the UserProfile component in the end.
So therefore, this is the user authenticated state
is a perfect example for a state
that we could manage with React context
or since this section is about Redux, with Redux.
And that's therefore what I wanna do now.
I wanna make sure that when we click the Login button,
we set the user to authenticated.
If we click the Logout button,
I wanna set the user to not authenticated.
And for this, in our store here,
we can add a brand new state,
a brand new piece of data.
Now, the question
is where we should add our authentication data.
We do have this slice, which we created here,
this counter slice
and in there, we manage the counter
and the showCounter state.
We could, of course, also add a new property
to our state here.
Let's say the isAuthenticated property
and set this to false
and then add a new reducer, login, for example,
a new reducer method,
and in here, we then set is isAuthenticated to true.
We could do this
but logically it makes no sense.
The authentication status has nothing
to do with the counter.
Whilst it would technically work,
in programming we typically wanna separate our concerns.
We wanna make sure that this slice really focuses
on the counter-related state and actions.
And we should create a brand new slice
for the authentication state.
And that's, therefore, what I'll do.
I'll rename this initialState up here
to the initialCounterState
because we will soon have more than one initialState
and therefore, I set the initialState property in this slice
to the value stored in initialCounterState.
And then we can add a new slice
below the other slice,
though the exact position does not matter.
But we can call createSlice again
to create another slice
and this slice also, of course, needs an object
to be configured, just as our first slice.
This slice will be configured in exactly the same way
just with different values.
So we add a name here
and set this to auth, for example,
or authentication, whatever you want.
And we also wanna assign some initialState here.
Now, we could create this on the fly here
or again create a separate constant,
which holds this initial state
and that's what I'll do here.
I'll add a const initialAuthState,
which again let's say is an object
where we have the isAuthenticated property,
which initially is set to false.
And then here I set initialState equal
to this initialAuthState value.
And then we need to register our reducers.
These reducer methods, which can change this state.
And here I think two methods make sense.
A login method for well, logging the user in.
And a logout method for logging the user out.
In both methods, we'll receive the current state
as an argument automatically provided by Redux
and we can then mutate this state,
even though we technically shouldn't
but as I explained, we can do it here
because under the hood,
our code will be transformed to actually not mutate
the original state.
So it's safe to do that here.
And we can set state.isAuthenticated
equal to true here in the login state
and here in the logout state,
set isAuthenticated to false.
And that could be our slice for the auth part.
So I'll store this in a authSlice constant.
Up here we have the counterSlice,
now I have the authSlice as a second slice.
And now we wanna add that to our Redux store.
Now, very important,
when you work with multiple slices,
you still only have one Redux store,
so you still only call configureStore once.
This does not change.
And this store only has one root reducer here
but as I briefly explained earlier,
this reducer actually does not just take
a reducer function as an argument
but also an object which acts as a map of reducers
where you can then have any key names of your choice,
for example, counter
and then point at your different reducers.
Here, for example, add counterSlice.reduce.
And then we also add auth let's say as a key
and then here we add authSlice.reducer.
And these individual reducers here
will then automatically be merged together
into one main reducer,
which is exposed to this store.
That's how we can combine multiple slices
and their reducers.
Now, our authSlice, of course,
also exposes actions, which we can use
and therefore, I wanna expose those as well.
So export authActions,
which is authSlice.actions.
So now we added this authSlice.
Let's now use it in our different components
and of course, definitely feel free
to try this on your own first,
tap into the store and use the auth state
to conditionally show the Auth component
or the UserProfile component in App
and in the Header to conditionally show these items
or not show them.
And make sure that you dispatch the login
and logout actions in the appropriate places.
Just one important hint,
since we are merging our reducers together here,
the way we access data in our store changes slightly
and we will need to adjust this for the counter as well.
If we currently have a look at our application,
you see the counter is not being output down there
because we failed to extract it from the store.
In the Counter component, our code hasn't changed
but the code here changed.
All we have to do to make it work again
is go to our selectors,
so to use selector, and when we drill into our state
to read a value from there,
we now need to use these identifiers,
which we assigned in this reducer map
to drill into our specific state slices.
So for counter, I use counter as an identifier here,
hence in the Counter component,
when we wanna access the counter,
it's actually state.counter.counter.
This might look strange
but with the first .counter,
we make React Redux aware of the fact
that we wanna dive into this slice in the end,
into the state produced by this slicer's reducer
and then in that state slice,
we simply have a property named counter.
If that would be named differently,
if that would be value,
then in the Counter component,
it would be state.counter.value.
But since it isn't value but counter,
I'll revert it and revert it there as well
and that's why we have state.counter.counter.
And for showCounter, it's state.counter.showCounter.
So when you do try this on your own
for the authSlice, you should take this into account
when you read data from the store.
And with that, try it on your own.
We're going to do it together
in the next lecture.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.