MERN Stack Project with React Redux and RTK Query

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
we will manage state with redux and request data with rtk query as we continue building the react front end for our mirnstack project [Music] hello and welcome i'm dave today we will add redux and rtk query to our mernstack project i'll provide links to example source code and all resources in the description below in the previous lesson we started building the react app which is the front end of our mirnstack project in today's lesson we're adding redux for state management and rtk query as the api layer of our react app a quick reminder that this mirnstack project tutorial series is not for absolute beginners i suggest you start with lesson one in the series and note the prerequisite courses i recommend for success with this mernstat course before today's lesson i highly recommend completing my redux course let's look at our starter code for today i'm at the package.json and i'm going to change the lesson five front end from the previous lesson to lesson six and that's the code we're starting with is from lesson five that we completed in the last tutorial now moving forward we need to add some more dependencies to our package to use redux inside of our project so i'm going to press ctrl in the back dick and now inside of this terminal window i'm going to type npm i for install and then we're going to add the at symbol and have redux js slash toolkit and then give a space and we're also going to add react dash redux press enter and it shouldn't take too long to add those dependencies to our package json and then we'll see them listed in the dependencies above looks like they're already there i'll close the terminal window we can see react redux we can also see redux js slash toolkit now available i should note the other starter code that i have added today is in the css file once again in the previous tutorial we stopped at line 179 i did not go over the css i just said you could use mine if you want to or you can apply your own and the same goes here now i added the rest of my css starting at line 180 and it's everything else you'll see including a couple of media queries that will make the font a little bigger on those larger screens i believe in the last tutorial i thought the font looked a little small so i've gone ahead and increased that size but this is not a css tutorial you can go over my styles if you want to or you can apply your own now let's move on to highlighting that source directory and let's create a new directory inside and let's call this directory app now inside the app directory we need to create an api directory so now i'll create that directory and inside the api directory i'm going to create a new file and i'm going to call it api and then with a capital slice.js i'm going to move just a little quicker today so i'll paste some code in instead of having you watch me type it out but then i will go over anything that i paste in and so this is our starting api slice you can see i'm importing the create api and fetch base query from redux here and what we're using this fetch-based query for is essentially what we would use axios for in another project or something similar so that's how you can think about fetch-based query you can see we are creating the api right here so we've got export const api slice and it equals create api then we have to set some things inside of it and you can see our base query is going to use fetch based query and here's where we provide the base url which in development is our local host at port 3500. we would want to change this of course when we deploy this project we provide a couple of tag types because these will be used for cached data so when we invalidate different caches or types we'll be referring to the note and the user data both and then we provide endpoints here with an empty builder now we are going to provide extended slices that we will attach to this api slice essentially for notes and for users and that's where we'll provide the details that would really be the actual endpoints but this just gets us started with the api slice we need now let's highlight that app folder and let's make sure we're not inside the api folder and create another file and we'll call this file store.js and we can confirm we're not inside the api folder if we close that and you still see the store.js in your file tree so what we're going to do inside of the store just to begin is very simple we import configure store and then we use configure store to create a store we just give the reducer an empty object and we go ahead and set dev tools to true because we may want to use the redux dev tools but now that we've created an api slice let's go ahead and pull that api slice into our store as well and now instead of an empty reducer we will refer to that api slice and we'll also provide middleware so inside of the reducer you can see we're dynamically referring to this api slice with the reducer path and then we have api slice dot reducer here likewise we have middleware here that now must be added to the default middleware so we can call this function get default middleware and then well here's the actual function it's passed in here and then we add with concat we add the api slice middleware there now again this was all covered inside of my redux full course so if this looks confusing it's a great time to go back and review that as well and now that we've set up our redux store and we have our beginning api slice let's go to the index js and bring it into our project so we need to import a couple of things now we need the store from our store file that we created inside of the app folder and then we also need to import a provider from react redux and then we can use that here in our project so just underneath where we have react strict mode we want to create a provider and we want to pass in the store that was created and then we close that and get the closing provider tag and of course we'll put that after browser router and before the closing react strict mode tag so now we have provided the store to our application now we're ready to move on to the features directory and if you remember inside of the features directory we have auth notes and users let's go to users first and inside the users directory let's create a new file and we'll call this users and then capital a for api and then capital s for slice so it's users api slice dot js i'll paste in just a little and go over this before we add any more so we're importing in create selector which we'll use later and then we're also importing in create entity adapter from redux js toolkit and then we're importing in the api slice that we created as well which we will use but first we create a user's adapter specific to our user slice here that we are using create entity adapter with now if you've gone through my redux tutorial you'll remember using a entity adapter we can get some normalized state here so we should start then working with data that has an ids array and then also has entities now the entities cannot be iterated over but the ids can't so we'll use the ids to get data from the entities essentially when we need to do that again if that sounds strange please refer back to my course but we will be using that as we move forward then if initial state exists in the user's adapter here we're calling that get initial state so we get that now i'm going to scroll up for some extra room and once we get up here to the top i'm going to paste in quite a bit as we get started with our users api slice but i'll go over this it only has the one end point right now but see we're using the api slice that we import right here and then as we define our users api slice variable right here that we can export we use that api slice to inject the endpoints into that original api slice and that's where we define our endpoints and we're only going to have one as we start out here so we're passing in the builder and it's our get users query so there we have builder.query and here you can see the query it's just going to the user's endpoint and remember we already provided the base query url inside of our api slice which was our local host at port 3500 so here we just have to provide that endpoint following the documentation we can validate the status now you may not have seen this before and it's a little strange because even as they note in their documentation currently their tricky api as they refer to it always gives this 200 status even if is error might be true but this is how they say to check or validate the status so this is exactly what i'm doing i'm making sure there is not an error and i'm also making sure that we do have a 200 status here now this keep unused data for and i've got it set very short to five seconds i'm only going to do this in development but you could remove this later on the default is 60 seconds which would be more like what you would want when an app is deployed and that's just talking about whether the data will be referred to in the cache or if it needs to request new data so we're just not keeping it that long here during development transform response this is very important especially as we're working with mongodb and getting data from our back end so here we get the response from the query and then you can see i'm defining load loaded users inside of this function that we can call inside of the transform response what i'm doing is mapping over the data and i'm setting the user id property to the value of the user.underscore id and the reason is especially with that data i talked about the normalized data using an id array it's looking for an id property not an underscore id property so if we didn't do that it wouldn't work out right and then of course we just returned the user there and then we use that user's adapter and it says set all and we're providing these loaded users which is the response data that has that new value at the id property so now we have returned that data and put it in our users adapter and it's stored as normalized normalized data with ids and entities now here this last part just provides the tags that can be invalidated now you could possibly get a result here that doesn't have ids now that's probably when an error has occurred or you've got something you didn't expect how i'm handling that is i'm just checking to see if there is an ids property with optional chaining and essentially if there isn't i'm just returning the user and the id list instead of the user type and id list along with mapping over those ids so any one id could invalidate it essentially if we don't get ids we probably didn't get the data we wanted anyway so that's just kind of a fail safe and now if you remember or know from rtk query it is going to create a hook based on this endpoint for us automatically so now let's scroll down to the bottom and we can export that hook so we'll have export const and it automatically generates a hook that starts with use and ends with query if it's a query and then it's whatever we named it which above was get users so this is use get users query and before we're finished with this slice let's go ahead and create some selectors and i'm going to paste this in and go over it it is exactly what i did in my redux course as well but what we've got first is select users result and now we're using the users api slice referring to the endpoints calling git users and then chaining the select method to it so this gets the query result after that we're creating a memoize selector notice we're using create selector here that we imported above and we pass in that result select user's result and then we have a function that has user's result and it comes in and grabs the data now i'm going to press alt z so this wraps so you can see my full note here which is normalize state object with ids and entities that are referred to notice this doesn't have an export so we're not exporting this at all we're just creating that memoize selector here to use in the next part and this is with git selectors so it says git selectors creates these selectors and we rename them with aliases during the destructuring here so it creates these automatically we have select all select by id and select ids and we're renaming them to apply them to users so select all users select user by id and select user ids now how we're creating that says pass in a selector that returns the user slice of the state so we're using git selectors on the user's adapter we have state coming in here's that select users data where we created the memoize selector so we're using that here with state and then you can see the null cloleskin operator so if that's null then it just goes to initial state but otherwise these are memoized selectors and they can come in handy when we want to optimize our application so now that i've saved this file i'm actually going to press ctrl a to copy everything we've put in here and then control i said control a to copy it's ctrl a to select control c to copy and then we're going to go to the notes directory and inside of it we'll create a notes api slice.js and i'm going to paste in what we had in our users api slice i'll once again press alt z so that wraps but now what i'm going to do is highlight the word user and now that i have that highlighted i'm going to press ctrl shift and the letter l and then i'm just going to type note and so you can see it changed every instance of user in this file to note and by doing so i just took a shortcut to creating my notes adapter because it's basically identical to the user's adapter at least as we get started here but we're just referring to a note instead of a user and as i scroll down i don't see any problem and we'll have a use get notes query that is created and everything will be created here including those memoized selectors that we might use including select note ids select note by id and select all notes now to quickly review how i did that so you don't have to highlight every instance of note there's two things to take into account one is the selection and so i selected all occurrences with ctrl shift and the letter l select all occurrences which you can also do from the selection menu that does not take into account wherever note or user was capitalized or wherever it was lowercase as we see here and notice all of mine changed automatically i'm doing that with an extension i'll save this file just so i don't lose any changes let's click the extension over here in vs code and i'll search for multiple and there it is multiple cursor case preserve i use this extension so when i select multiple cases essentially when the word user was lowercase or uppercase and i replaced it with the word note i just had to type the word note and it applied the upper case in the same areas that user had upper case and of course lowercase the same so this is a very useful extension multiple cursor case preserve if you want to apply that to your instance of vs code as well but that helped us quickly and easily create our notes api slice to get started now in the previous tutorial we already created a users list component and a notes list component let's go to the users list component you can see this was just a placeholder so far now i want to come to the top of the file and i'm going to import that hook that rtk query automatically created for us that we exported the use get users query and now inside of our functional component the very first thing i'm going to do is actually use that query and you can see we're going to get several things from it we're going to get data back that i'm going to rename as users we're also going to have several states that we monitor here we can check and is loading and is success and an is error and if we have an error we can find out what the error is and all of this will help us conditionally render some content so underneath i'm going to define some content with let content variable defined here and then we'll check is loading and if that is true we're just going to set the content to loading or if you have a spinner component you like you can use that there as well next is error we're going to have content set equal to a paragraph with an error now let me press alt z once again to wrap this so you can see everything and i'm checking to see if there is an error here in the class name so you can see i'm applying two different class names based on that if there is no error if that is false this is off screen and if there is an error i'm applying the error message class and then we're displaying the message itself now notice the error doesn't just have dot message it has data first so we're going error dot data dot message and i'm using optional chaining there just to be safe and now let's replace the return here inside of our component and instead i'm going to paste in what happens if we have success i'll delete that extra line and let's look at this so if success then we're destructuring the ids from that user's data remember we renamed the data that we received from our hook users this would also have an entities that we could destructure here as well so the ids is just an array of the user ids now we're creating our table content and we're making sure there are ids that there have length on that array and if so then we're mapping over those ids and you can see we're passing the user id in here from map and then we're providing a user component that we haven't created yet and all this user component receives is the user id now it has to have a key as well as we map over but we're providing the user id for both of those and if there is no link to our ids array then this is just null and then we have content here that's on multiple lines so that's why we have our parentheses and you can see i'm creating a table now this table has several classes applied that apply to the css that i have provided you can see user names roles and edit and this is all inside the table head and then we have the table body that just gets our table content which was our mapped data from above now something to note about the tables in this project is i am setting them to display contents which lets me flatten the table to actually apply css grid to that now if you have not done that before you might be interested in the css you might also be interested in the final project of my css course on my channel where i do that exact same thing so grid needs a flattened structure tables are not usually a flattened structure but you can provide a flattened structure to grid if you set some of these elements that are the parents to that display contents and you can see at the bottom we are exporting the user list component and that should finish the userlist.js now we still need to create the user component that we're using here inside of map or we will have an error and this just won't work out right so now let's create a user user.js file i'm going to paste in some imports that we can talk about and then we'll create the component underneath so we are using font awesome icons as we previously set that up in the last tutorial so here at the top i'm importing the font awesome icon component and then the icon that i want to use i've also got use navigate from react router and then we're bringing in use selector from redux this is where the ids will come in handy because we're also bringing in that memo wise selector we created which is select user by id so underneath using react es7 snippets i can type r a f c e press tab and we get our functional component named user and we know we're bringing in a user id so now let's start just inside of the component and we're going to bring in that use selector and we're going to use that select user by id selector pass the state and we pass the state and that user id here and we get our user back also we're going to pull the navigate function from use navigate and now instead of the return that we have here let's start out with an if statement we can say if we have a user so if that user does exist we're going to do something here but then let's also have an else return null just in case we don't have a user and now i'm going to scroll to give ourselves a little more room to put some things inside of the successful part of the if statement and we'll start out by defining a few things one is a handle edit and this is going to call navigate and it's going to go to dash users and then whatever the user id is is going to finish out that url and we can set that up in our app.js with react router the next thing i'm doing is pulling all of the roles from the user roles array setting them to a string and i'm also replacing the commas with a comma and a space so really what we're doing here is making it just look a little bit better with formatting so instead of all scrunched together we get a comma and a space instead of just a comma then i'm defining a cell status and this is helping me set an inactive class or not essentially on the active user and now let's go ahead and put in the return data that will use those and so here we see a table row being created that will go into the previous table that we started in the users list and now this row has several classes let me see if i can press alt z and get a little more to display there wasn't much wrapping but what we've got are some table cells here and we're setting that cell status in each one if they are active or not likewise we're using that icon that we imported here the pin to square that we would see which kind of indicates edit and we're calling handle edit if that is clicked so let's go ahead and save this file and let's not forget to import it into our users list as well so we need to import user from dot slash user and after we save that we're ready to check this out in our application but we can't just start up the front end without the back end and the last version we have of our back end code is the code repository from lesson four so open up another instance of visual studio code and in that instance you want lesson four i'll drag mine over right now as you can see it now on the screen and i've got lesson four here in the package json i could make this full screen as here as well so now that i've got the lesson four code up in another instance of visual studio code i can press control on the backtick type npm run dev and we'll make sure our backend code is running and it's ready to respond now to the front end code that we're creating so now that i have that running i'll minimize that and we've saved our changes here so i am ready to press control in the backtick as well in this instance of visual studio code and type npm start to start up our react app now i'm going to drag it to the left as i have a browser here on the right and then we should see our app start up and we do the font might be a little bit larger than you saw from the previous lesson as we've applied that extra css but now we're going to need to enter in the url to navigate to the dash so it would be at slash dash and from there we can see what the employees or the staff of dandy's repair shop we'll see when they log in except for maybe some auth details that we haven't added yet and we should be able to navigate to the users list by clicking this view user settings so if we do that now we see our grid table here and once again i'm taking that html that is a table and i'm turning it into a grid and you might be interested in the css for that but overall we've got three employees that i added you could add your own using postman as we had seen previously in tutorials as we were building the back end and you can see it displays their username their roles and the edit area now this edit area won't currently take you to any page it would probably give you an error because we haven't created that page yet to edit that information but our users list is working as we expect it to so now i'm going to drag visual studio code back to a full screen and close the terminal i'll just leave it running because we'll eventually check that again and now we're ready to update our notes list so at the top we need to use that same query that was created in the notes api slice just like we did with the query that was created for the users api slice so now we have use get notes query and now inside of the functional component you should notice this will be much like we did for the users list so what we have here is that use get notes query we're bringing in data but we're renaming the data notes instead of users we're going to check is loading is success is error and if there's an error we'll look at that error so i'll scroll down once again press alt z so any code going off the screen wraps to the next line and we're checking is loading and once again providing a loading status if that is the case for content likewise we're checking is error and we're applying those same classes for an error message if it needs to display and remember the error has dot data dot message instead of just error.message as you might be used to and now i'll scroll up because we're going to replace this return and we'll replace it with what happens if we have success and here for is success we're once again destructuring the ids from the notes data so this could have ids and entities and in the future we'll actually come back and use the entities here as well but we're keeping it simple for now and then we have the table content that we're creating in the same way we created table content for that users table and we're passing the note id into a note component that we have yet to create you can see this table is a little larger here and it has some extra classes applied which is why you see this wrapping down so we have more columns that we'll be able to see on a larger screen but i have applied a media query that hides some of the columns for a smaller screen and then we have that table content going into the table here as well and then we export the notes list and that wraps up everything inside of this notes list and of course if i went over that too fast you'll see all of this code available in the course resources and now let's create our note component so note dot js and we'll start with the imports much like our user.js component we're bringing in font awesome we have the pin to square icon and use navigate from react router dom we also have use selector and now a memoized select note by id from our notes api slice i'll type rafce using react es7 snippets extension we quickly get our functional component and then inside this functional component we'll start by using our use selector hook and then we'll select note by id pass in the note id here then we're also pulling the navigate function from use navigate and now we'll put a conditional here instead of just the return so we'll say if we have a note we're going to do something and then we'll say else return and we'll just return null now inside the successful if part let's go ahead and define a few things here we have a little more data we're handling inside of note than we do with users i'm going to press alt z once again and i'll even press ctrl b to hide that file tree temporarily but it still wraps down just because it's taking a little longer here with the dates so we've got to create a date and an updated date that we get from mongodb about each record and here we're applying this to locale string and here i'm providing the us area for this now you could provide your area if you want to as far as our stakeholder dan d's repair shop i'm considering them to be in the us as well now we're providing the day value as numeric and the month as long for both of these and then we have a handle edit function that is going to navigate us to dash notes and then the note id and that's where we would be editing the information for the note and we'll eventually need to add that routing to our app.js as well now underneath this will put in the successful return and this once again is creating a table row you'll want to apply these classes if you want to use my css notice here i've got a ternary based on whether the note is completed or not so it gets a different class based on that completion other than that we're displaying these others inside of table cells but then they also have classes based on what each piece of information is and eventually we have a table cell that has that font awesome icon that indicates an edit once again and it calls handle edit now with those changes saved i'll press ctrl b to show the file tree again back in the notes list we need to come back to the top and import note so it can be used and it comes from dot slash note after we've saved that we should be able to see our notes list now remember if you're creating users and notes with postman you want to create the users first because you have to have those users to create notes so far and that's what i've done so i'll drag this to the left and i can see an error because inside of note i forgot that we were bringing in the note id so i didn't put it at the top and it needs to be coming in as a prop so here we've got note id as well let's save that easy to forget when you're moving quickly move it back over and here's our users page once again so this is working let's go back to the home and let's see if we can view the tech notes yes we can notice the completed here is at the top that's something we'll talk about in a second right now they're just in the order they were created so we've got mrs smith's computer we've got foo city schools which is the city where dandy's repair shop is and we've got bob jones's iphone now we just see three columns here so let me drag this to the full screen and you can see the media query is actually hiding some of the other columns based on the screen width so now we can see the created updated and the owner of the note who the note was assigned to essentially and then we've still got the edit icons over here now that we've looked at this a little bit let me drag it back to the smaller view we can still see the status here either completed or open it would be nice probably a good feature to think about and include even if our stakeholder didn't ask for it directly would be once a note is completed to not leave it at the top anymore just because it was created first let's put the open notes on the top and any that are completed down at the bottom instead so i'll drag the code back over and we can do that inside of our notes api slice where we have our entity adapter here where we create the entity adapter we can provide a sort comparer function so i'll paste this in and we can see what it is doing so this is much like your traditional javascript sort we take a and b and then we're looking to see if the a completed value is equal to the b completed if it is it gets a zero otherwise then it's checking this once again looking at a completed and it either gives it a one or a minus one so it may be just a little more complicated than that traditional sort that you're used to but what we're doing essentially is putting the completed at the bottom so if it is true otherwise the open status is at the top so if we just put this in and then we drag this back over and check our page we'll need to refresh to query that data once again now mrs smith's computer is at the bottom of our list and any others we would switch to completed would instantly come below as well we have covered a lot in a short amount of time as far as redux and rtk query goes now in the next lesson we'll cover mutations which also covers the editing and posting and deleting so the crud operations but those are the mutations not the queries as they're referred to in rtk query remember to keep striving for progress over perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 21,530
Rating: undefined out of 5
Keywords: mern stack project with react redux, react redux full stack project, mern stack project, mern, mern stack, mern project, react, redux, rtk query, react redux, mern react, mern redux, mern react redux, mern redux project, mern stack redux, mern stack react, mern project redux, mern project react, redux toolkit, mern redux toolkit, react redux toolkit, mern react redux toolkit, mern stack tutorial, js, mern stack project with redux, mern stack project with redux toolkit
Id: TPAAQnVxc-I
Channel Id: undefined
Length: 35min 52sec (2152 seconds)
Published: Tue Aug 16 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.