State Management in React | Context API useContext | React Tutorials for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello and welcome hi i'm dave and this tutorial is part of a learn react tutorial series i'll put a link in the description to the full playlist okay today we're talking about use context in the context api we're not adding any new functionality to our blog application we're just going to refactor to use context instead of drilling props down because that can become unwieldy and we can see really that our app.js is full of code we've put in all of our logic as well and so we've just been passing it all down this once again might not be the most efficient but it certainly helped you learn how to pass props down to components and we've been drilling those props as the statement goes however we're going to eliminate all of that today by refactoring and we'll have a much neater app.js file and we'll be able to subscribe to context and use the use context hook to pull that information in so let's get started we'll highlight our source folder in the file tree and here i'm going to create a new folder and call this folder context inside the context folder i'm going to create a new file i'm going to call this data context you can have more than one context per application i'm just going to create one today as we have a small application but imagine having a user section where the user entered information for example and you might want a completely separate context where you manage state with that here we're going to go ahead and start with an import statement and we need create context i'm going to import this from react so while i'm here i'm going to go ahead and import use state and use effect as well because we'll be using those inside of our context now from vm is not correct i want from react and now that we have that i want to go ahead and define my data context i'm going to set this equal to create context that we just imported and this will have an empty object inside to start out with from there say export const and i'll define our data provider that will provide the data to our different components and here we'll have a parenthesis and then inside is a destructured children and this will refer to the components that are within the data provider and then the data will be available to the children of the data provider so now that we have defined our data provider let's go ahead and put a return statement in it and inside the return we'll have a data context dot provider and here we'll have a value and now two curly braces and i'm going to go ahead and press enter to have an extra line and then we can close this out with a greater than symbol but this is where we'll put the different values what have been props that we've been passing down we can now pass through the data context dot provider and our data provider will provide it to the different components as we request them with the use context hook and so we'll add that all of that in just a minute right now let's finish this and here we need to have children in the jsx and after that we need to close out the data context.provider in the jsx we can save that much and i have that formatted but we still need export default data context here at the bottom after we save that we really have our skeleton for our data context we need to move state and anything else we want in here that we will provide through the data provider let's go back to the app.js and now we need to import our data provider and this will come from dot slash our new context folder and inside the context folder is the data context and now we can use the data provider to provide data to any of these components right now of course it's still a little large here as we have all the different props that we're drilling down we will clean this up in a little bit but what i want to do is just essentially put the data provider here around all of the components and then the components within can subscribe at will to the data provider now that we have that i'm just going to highlight everything and tab them in because the data provider would be a parent to all of the components within and we can save that now the data that comes from our context from the data provider will be available to all of the components within if we choose to pull it in using the use context hook let's go ahead and scroll up here in the app.js and start moving some of our state and information over to our data context while we still leave it here as well so we can keep the app working during the transition here as we refactor so i'm going to highlight everything after the components here so i've got the route switch and history from react router dom and everything below it except the data provider and so down to axios fetch i'm going to copy all of that and put these import statements in our data context as well now of course we don't need the use state and use effect from react we've already got that we won't need the route and switch but we will have use history here and then we've got format now when we get to our api we have to consider where this file is we have data context inside a context folder so that's different we need to come up out of the folder with two dots and then we'll have the api and then the post then the same for the hooks we just need to add a dot in front of each one of these so there's two dots and that should be good once we save that we can go back to the app.js and start to grab the rest of this information as well so let's grab all of the state that we have here let's grab the axios fetch the two use effects as well copy all of that control c since i'm on windows and now inside the data provider we can paste that right in just like we had it in our app except now it's in the data provider of course we've left it in the app for now just to keep the application working we can also take all of this logic the handle submit handle edit and handle delete copy that and put it in the context as well now if you have a little bit of experience with react you may be thinking wait what is he doing well right now we're just dumping it all everything that we had in the app app.js we're putting in the data context we can get a little more organized later we can think about efficiency some this is a small app react is already very efficient but we'll talk about some of those things here in the future right now just taking all of that stuff we had in app.js and we're moving it into our data context and now at the bottom we're not providing anything yet but we will right now we've left everything here as well so let's scroll down in the app.js and the first thing we have is the header you can see the header is receiving a width prop as well as the title we'll leave the title here because you don't have to go all one way or the other you can still pass a prop down like the title while pulling a prop like width from the context so that's what we're going to do back here in the data context we've already defined width above so let's put width right here if we provide more data i'll need to put a comma after that but we already have width defined i believe yes we do right up here on line 19 in the context and so now we're passing it through from the provider and now let's look at the header file in order to use width from the context instead of being passed in as this prop which we can remove from the d structure here let's go ahead and use an import at the top and this will be to pull in use context and that will be as the other hooks from react and then we also need to import our data context that we defined there we go it already helped me out from the context slash data context now that we have those we need to define width since we're no longer pulling it in as a prop above so this would be const and then width and then this will be set equal to use window size oh i'm sorry not use window size that's where we're pulling it from in data context this will be equal to use context and that will be from the data context so if you had more than one context you can see now how you import it and you would pass it in to the use context hook and we want the data context so we pass that in to the use context hook here and we get width it's no longer being passed down but much in the same way we're defining it near the top of our function here just using the use context hook and we can save this and now if we go to the application the width should still be working and we still have an icon there we can go ahead and refresh to see if we have a problem no problem i'm going to open up dev tools and even resize and yes it already resized to a tablet let's go ahead and scroll and it's a phone size it's a tablet size soon there we go and then a laptop yes not going to worry about the warnings right now we've defined many things that aren't being used but we'll continue to switch each component over and we'll slowly eliminate warnings and errors as they arise okay back to visual studio code i'm going to copy this use context import and data context will need that at the top of every component that uses a context subscription and so now besides the header let's look at app.js we can eliminate this width as well now we want to go to the nav and it receives search and set search so i'll save the app and let's open up the nav file i'll need to paste these two imports at the top same as we had before with the header and then we also want to take a line like this that uses the context and put it into our nav and you'll see a pattern emerge here where we're no longer destructuring as props but we can just put the same props right inside of the used context as we use the hook and so then we can eliminate these props here in the function parentheses okay if we go back to the app.js now we should be able to eliminate search and set search from the nav we can already see how this is cleaning up a little bit now we see home receives posts fetch error and is loading and we also need to pass search and set search in the context if you remember in our data context we had only passed with before so we need to remember to do these as we pass everything along and now we said our next one home is going to receive search results even though we labeled it as posts here it's search results fetch error and is loading so let's set search results fetch error and is loading let's save that much and let's go ahead and pull up the home component okay we'll need to once again copy from header or if you just memorize the imports and type them that will work as well but we've got use context imported and our data context and now also in the header we'll need to use context and pull out what we need from it and again even though this says posts that's because we had labeled it that before it came in so we'll need to switch that to search results if i can highlight it all there we go search results [Music] let's eliminate the props that were being destructured there and now inside of our function we need to change a couple of things because this should no longer be post it would be search results and the feed even though they'll be labeled as posts after it receives the search results as posts and we can save that so now we have received all of these with context and we did the same with the nav and we received those here with the context and then of course in our data context we had to provide all of those values here let's go back and see if our application is working it looks like it's working let's do a reload so far don't worry about the warnings of course we've got many things defined right now that aren't being used yet we can still search so everything is working as expected so we're just replacing just a little bit of each component as we go let's go ahead and minimize chrome if we head back to the app.js we can eliminate some more here we have now eliminated all three of these props that were being drilled down to the home component and if you remember some of the components we were able to eliminate all of those and when they didn't have any props being sent to some of the components we were able to just specify inside of the route which component we were routing to like this and so that's much cleaner now let's look at the new post component that receives even more props i'll save i'm going to go ahead and close up the open editors at the top so we have a little more room here and we want to scroll down and choose the new post js you can see it's receiving five different props that are being drilled down so once again i'm going to go to the header file copy these two import lines then go back to the new post and at the top it had no imports before we'll import both of those lines and then we'll take our use context line as well go into the new post paste that in and then take everything that we were receiving as props and we'll receive those from the context and now we'll eliminate what we were deconstructing and save and we should still have all the same functionality because nothing else has changed it's just in how we receive that data let's go back to app.js let's go ahead and remove everything here including the closing route and we'll just use the component and pass in new post and we'll save now let's go to our application and let's go reload once again just to make sure everything should already be fine let's go to new post and let's call this post five oh and you know what we forgot to do we've got an error here set post title is not a function and that is because we didn't take all of those props and send them through the provider yet so this is what we need to make sure we have done handle submit post title set post title post body and set post body go to our data context and make sure all of these are being sent through the provider and once we save we should be able to go back and without error reload the app i'll go back to home and reload the entire thing just to make sure let's have a new post and we'll say post 5 just checking submit and yes we have post 5 just checking so if you get that error just like i did you'll know what is happening you need to make sure you're sending those same pieces of state and maybe even like the handle submit function so maybe even some logic being sent through the data provider if that is how you are providing it to the component let's minimize chrome and we're back here at the data provider now let's go back to app js and we'll clean up the next one which is edit post you can see it's receiving probably more than any other component was and so we'll need to make sure we're sending all those same props through the data provider let's go ahead and change this right now to just have a component it says edit post we'll save that which will break the app momentarily let's go to the edit post file and i'm just going to open up nav js this time copy those same two lines i'll go into edit post and i'm noticing at the top i'm already importing use effect from react so i don't really need the separate use context line i can just put use context in the same line there after that i'll go back to the nav again and we're going to go ahead and copy that use context hook line and once we're inside the function here i'll put the use context line i'll cut everything out that was received as a prop and put it into the use context line here eliminate the curly braces from where props were received and save now everything should be okay except we need to make sure all of this is being passed in the data provider as well so we'll put a comma after the set body and we'll paste we'll make sure we don't have any duplicates here we have posts handle edit edit body it looks good so we can save that i believe we've already made the changes in the app.js yes for edit post let's once again go to our application let's pick our new post five let's edit the post and change the five to the word five and just checking in and we'll submit and yes edit post works just fine let's go ahead and minimize chrome not much left to go on this initial refactor but we've got one more component that is receiving some props here our post page so let's scroll down to the post page let's once again copy our import lines use context and data context and on the post page we can put those right here now we'll go ahead and copy the use context line for the hook back on the post page again i'm going to put that right underneath here and then we'll take posts and handle delete and we'll paste those in here and remove the curly braces and now we need to make sure posts and handle delete are already in the data context and if we select data context post was already here but not handle delete so let's go ahead and add that as well and save i'm going to close a file or two at the top just so we can see the ones that we want to have open here's app.js and now we can change this up as well and make it the component close out the route and if we look at our app.js file now it is much much cleaner the data provider surrounds everything and of course we have our routing in here that we previously had including our switch statement but even up above we haven't removed these but we will be able to now because you notice we're not passing any of them down whatsoever there are currently no props being passed other than what we have for our route and we're saying hey this is what the component is so that is much cleaner let's make sure our application is working so we'll reload let's go to post five looks like we can still edit the post i'll remove in here that's good we can delete the post it deleted no problem we should be able to search so if we search for three yes everything in the application seems to be working just fine let's minimize in chrome and now let's go ahead and remove everything that we really don't need in the app.js file i'm going to remove use history as we now have that in the context we won't be using state or use effect or any of the rest of these except the data provider so what we're left with are the components route and switch then from react router and our data provider we're able to remove all of these pieces of state and use effect we should be able to remove all of the different functions we have handle submit handle edit and handle delete and we can save and now our app.js is much much smaller so we're importing in the components the routing and the context and look at this function it is so much smaller and easier to manage than what we previously had as we were drilling all of those props let's once again go to our application reload and make sure it's working but it sure looks like it is and so now we're using context for all of those things let's minimize chrome again and let's talk about how we've organized everything app.js looks much better and our context here has everything that we previously had in that parent component and of course when a parent component renders then so do the children of the component so it was causing lots of re-renders but this still could cause quite a few because everything that subscribes to the context when the context gets updated so would the component so let's think about some of what we're doing and are we actually doing it as effectively and efficiently as we could if we go to app js and once again look at each component we could stop and think that really the header does not need to receive any of the post data it's only receiving this title prop and then we're passing a width to it if you remember and that determines the icon for the header alone so it doesn't really need to be involved with the rest of this likewise the footer isn't receiving any data either and it doesn't need to be there so we could move our data provider and we could wrap it around everything starting at the nav and ending it at the switch route because that is the area that really needs the post data and so we could save that i'll eliminate these lines here and now that we've done that we need to change the header just a little bit because right now it does depend on that data from the data provider so let's go back to the header and we can go ahead and remove these imports and let's think about how to get the width well it never had to be passed down to begin with so what we could do with the width is just import the window size hook or use window size and that would be from hooks slash and then i believe it's use window size there we go and now that we have that instead of defining with from use context or just to find it and use window size and that's a very simple change but that totally decoupled the header from all of the data that was involved with the posts and we can go back to the data context and we can say we don't need this use window size import anymore likewise we don't need to define width inside the data context from the use window size and finally we don't need to pass it down at all it can just be contained within the component itself the header component can just use that hook and really if we stop and think about some of our other components some of the data that we previously had in a parent does not need to be passed down either so handle delete is probably only going to be on the post page where the delete button is handle edit well that's probably only going to be on the page where the edit is and handle submit probably only on the new post page where we submit a new post so let's go look at the new post page and on the new post page if we stop and think about it this post title and post body along with the set functions is really only linked to this form it has no other role in the application so that could just be state that we keep within this component without sending it to a context because it doesn't need to be shared with other components and really that's what the context would all be about so at the top let's just import use state and let's go back to our data context and we'll copy those lines where we had the post body and post title and we'll just cut those right out of here and we'll go back to the new post and we'll take these and we'll set them at the top and we can eliminate all of the post body and post title that were imported and now the same with handle submit this is the only place that that function is called we might need some other state that is used inside of handle submit but we could easily import that from the context so let's go back and grab that function as well and let's find handle submit here it is we'll take this and just cut it out of our context and we'll take it to the new post component and paste it in and now that we have a handle submit here as well we know we won't need it but i'm not going to get rid of the use context line because handle submit probably has something else we need related to posts everything else is looking good there so now let's go ahead and look at this function clearly it uses posts so we're going to need the posts from context it also has set posts and does it have anything else we'll need no set post title and set post body are now contained within it looks like we're going to need to import the use history from react router though so let's go ahead and do that [Music] import use history from react router dom and then we'll need to define our history to be able to use it we'll set that equal to use history and save and we'll see if our function will continue to work it also has an api call in here so if we're going to use the api we do need to import that into the function as well so we can import api from dot slash api slash posts there we go and save now we have the api in here to make the api call and handle submit as well and everything else looks good so we have our handle submit function and we're containing the state within the component that really doesn't need to be shared and we're pulling in the state that does need to be shared between components and here that is posts let's save this we'll go back to our context and we already removed the function and we already removed the state that we won't be using here but let's go down and what we do need to do is remove the post title post body and everything that we had right here for that because it no longer needs to be passed through the provider if we go back and now look at our application we've got an import which falls outside of the project and that is the use hooks that must be in the header js let's go ahead and fix that import it looks like i have an extra dot in there and let's give this another shot our new post js needs the format import that we also have in context so let's grab that as well put this in the new post component as it's used in the function right here and i missed that now that we've got it let's go ahead and reload the blog seems to be working let's make that fifth post again set posts is not a function which means we did not send that through the context previously if we come back go to our context i believe we sent posts before but we never sent set posts let's save go back to our application i'll once again go to home refresh just to be safe new post fifth post again and there is our fifth post and now everything is working as it should and it actually looks like the last one did post so i'll go back and delete it as well and now we're just left with the last fifth post i'm going to minimize chrome and we can look at the next change now that we did that with the new post page let's go ahead and look at the post page as well and say what can be sent here or what could be actually contained in the component that doesn't need to be sent here well posts is something once again needs to be shared amongst all components but handle delete is really only needed in this component that is once again logic that could just stay right here so let's make some room and we'll go to our data context and we'll pull out the handle delete just cut it right out of the context and while we're here we'll go ahead and delete it out of our provider i'll eliminate the comma before it we'll save that and on the post page we should be able to paste it right in but once again the function may need something that we weren't already bringing in so let's take a look oh this is handle edit wait a minute i need to put that back for now and get handle delete here we go i'll just save go back to the post page paste in handle delete and save but what are we missing we are missing the api for sure so we need to import api from dot slash api slash posts and after the api we have set posts coming in no we don't yet so let's go ahead and do that instead of the handle delete but we previously were bringing in from use context and now that we have set posts we're going to need history again from react router dom we already have some from react router dom up there so let's just bring in the history as well we'll need to define history i'll do that right here so we'll say cost history equals use history and now that we have the history we have set posts we have the api i don't think i'm missing anything else but you never know we'll go ahead and save that let's go back to chrome and see if our application is still working we'll try to delete this fifth post i think i'm going to reload first and attempt to delete and the delete continues to work everything is good let's minimize chrome and keep working let's take a look at app js now we have already handled the post page and the new post so what might be logic that would be an edit post that the rest of the application would need let's look at our context and handle edit the function for sure pretty much what we had here handle edit edit body set edit body edit title set edit title those can all just be contained within the component once again because the rest of the application does not need them so we'll just remove those here from the context provider we'll save that let's grab the state first and then we'll come back and get the functions so all of this state right here is no longer needed inside of our context we can just move that inside of edit post and now that we have edit post open we'll put the state right here at the top and we are going to need to still bring in posts and probably set posts so we'll once again pass that right there we've got use effect here with post set edit title set at a body that is fine we're already bringing in use effect here so we need to bring in that function so let's go back and now grab handle edit cut that out of our context as well go ahead and save the context but in edit post we can put the function then right underneath the use effect and save and let's see what else we still need in here we're going to need format again it looks like we'll also need the api and we're going to need history for sure okay so at the top we've already got params and link from react router let's get use history then let's go ahead and define that history as well so we'll say cost history equals this history let's import the api import api from dot slash api slash post and save so now we have the api and we still need the format so was that on the post page i don't think so i think it was on new post that we had format there's that import and we'll put this back on the edit post page and i think we have everything then needed for the handle edit date time updated post so format api history it all looks good let's go ahead and see if the app is working as we expect it to well wait a minute let's see if we eliminated for everything from the context yes it looks like we did so let's go back and see if the app is working like we expect it to oh there is a problem use state is not defined we can't forget that at the top of edit post i believe yes we're going to need that right here we brought in all that state and forgot to import use state now that we have used imported maybe everything is going to be working it sure looks like it let's try to edit our fourth post some more testing let's say words press enter and yes it is working with everything now working we can see we're getting a warning that we've got some definitions inside of context that are no longer being used that is because we have paired our context down so let's look at the context and say we no longer need the api well this is the edit post let's go to the context there we go we no longer need format or api and do we still have use history inside of here no we are no longer defining history either so we can remove that as well and let's look at the line use history there we go and save so now our context is much smaller than it was the posts and the search are definitely tied into each other because once we receive the posts then we have to set the search results based on what if anything is being searched for so this is pretty much our data that we now have and of course we get a fetch error is loading and we're calling our use axios fetch right here inside the context because it can be called inside of a function like this in react or a react function if you will not a traditional javascript function but we're just grabbing it right here instead of putting that in the home so this is working for us right now and we've contained much of the component logic that's just related to the specific components within those components hey thank you guys so much for liking the video if it helped you get started with react also i appreciate you watching and subscribing it's helping my channel grow take care and i'll see you again very soon
Info
Channel: Dave Gray
Views: 1,975
Rating: undefined out of 5
Keywords: State Management in React, state management in react js, state managment in react js, state management, react tutorials for beginners, react, reactjs, react js, react context, react js context, reactjs context, context api, useContext, useContext hook, react useContext, react js useContext, reactjs useContext, manage state, manage state in react, react context api, react js context api, reactjs context api, context api tutorial, context tutorial, Js, React state management
Id: ngVvDegsAW8
Channel Id: undefined
Length: 39min 31sec (2371 seconds)
Published: Tue Aug 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.