تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Introducing Context API0:00

I wanna quickly talk to you about the Context API and while I don't think that we should be using the Context API in this specific app, I think it's important that you understand what it is and you kind of know when is a good time to reach for it. Okay, so if we look at our main app, that TSX file, uh, you can see here we have this liked and setLiked state that we've set up and if we take the puppiesList specifically, we are going to go on the little trail.

Prop Drilling Problem0:31

and if we take the puppiesList specifically, we are going to go on the little trail. So we pass that state to the puppiesList, the puppiesList receives it and basically just passes it along to the PuppyCard and then the PuppyCard receives it and guess what? It passes it along to the likeToggle. And finally in the likeToggle, this is when we make use of dislike and setLike in the logic here. I just wanna reiterate that there's nothing wrong with this.

of dislike and set like in the logic here. I just wanna reiterate that there's nothing wrong with this. I don't think that we should change things here and matter of fact, after this lesson we will roll back, but I wanna show you using the example here of the puppies list and the puppy card. If you think about it, both of them, the main reason why they received the like and setLike is purely to pass it further down. So the puppies list receives that does nothing with it,

and set like is purely to pass it further down. So the puppies list receives that does nothing with it, just passes it along. And then same for the puppy card, it receives it up here and then passes it down down here. Both the IES list and the puppy card component act like sort of a pass through where they receive the states liked and setLiked and just pass it along. They don't need to know about it

and just pass it along. They don't need to know about it for any other reason than just handing it over to the next one. This makes this component and their props API feel overly complicated. Again, it's not a problem, but imagine we were passing down this disliked state, another three, four components deep. This is where you would probably think about reaching

Creating Liked Context1:50

another three, four components deep. This is where you would probably think about reaching for the context API. All right, let's create our first piece of context. So you can think of the context API as sort of a magical way to bypass or shortcut the needs to go through multiple components. If you have some data here and you want to pass it all the way down there, there's a secret little back door

and you want pass it all the way down there, there's a secret little back door that will take you all the way straight to the destination. We'll create a new file for this. So in the src directory, I'll create a context directory. You don't have to but it makes sense and let's call this one likedContext.ts. Alright and let's export a account called LikedContext. And this is going to import the createContext.

and let's export a account called LikedContext. And this is going to import the createContext function from React and we will pass null as a default value and we'll want to define the shape of what data this context should hold. And here I can in angle brackets specify an object. So we are going to want our likedState, which remember if I look in app.tsx is an array of puppyIDs. So let's paste that here

of puppy IDs. So let's paste that here and I need to import the puppy type. And then the setLiked is going to be our dispatch setState action, which can be a puppyId or it can also be null since we define it null here. And whoops, we're missing a closing bracket here. And so this is already serviceable and we've done this in a separate file because we are going to import it in different files.

Adding Context Provider3:17

and we've done this in a separate file because we are going to import it in different files. So first let's go in our main component in app.tsx. And here I'll use this context to wrap all the parts of the render tree where I imagine I would want to use this liked state. So clearly it's these two things. So let's at this level here start typing LikedContext and we should be able to auto import it. And so I will wrap the parts that needed it

and we should be able to auto import it. And so I will wrap the parts that needed it inside disliked context. And now is the reason why we specified a type in our context because now it's going to tell us, hey, you need a value prop that has liked and set liked. So this state is defined here and now we can pass that to a value prop to our context just like this. So this is one of the two parts of the context API.

to our context just like this. So this is one of the two parts of the context API. We have a context wrapper or context provider which is going to make that data available through the value prop. And then where we want to consume that data, uh, we are going to have a context consumer that's going to be able to access what's in that value. So liked and setLiked. So check this out. I'm going to temporarily break the app by deleting this, but

So liked and set liked. So check this out. I'm going to temporarily break the app by deleting this, but before I do this, let's verify that our like state is currently working and sure is, okay, so now I will delete this disliked and set disliked props on the puppies list and I'm expecting the app to explode here and sure thing it does. And if we open the console, you can see there's an error on the likeToggle component,

And if we open the console, you can see there's an error on the likeToggle component, which is the final destination, the recipient for our liked state. Okay, so let's continue breaking up further in the puppiesList. I will remove the liked and set liked props and the type and I will not pass them further down. And you can already see how much simpler the puppiesList component now feels.

And you can already see how much simpler the puppies list component now feels. And we'll keep going here as well. We remove the type and the liked setState and we do not need or want to pass it down. Alright, that means probably I can remove also the dispatch and setState action types at the top of the file. And we have significantly signified the puppies list and puppyCard components. And now if I go in the likeToggle, which expects

Consuming Context in Components5:21

list and puppy card components. And now if I go in the like toggle, which expects to receive liked and setLiked will also remove these and these and we can also remove the dispatch setState action imports And now is where we'll reach for this little magic backdoor to reach for our contact value. So we wanna keep all of this code intact. All we want to do is find another way to have access to liked and setLiked.

All we want to do is find another way to have access to liked and set liked. And so inside the LikeToggle component, I will go and this structure React API called useContext. So let's import that and the thing I want to use is this dislikedContext. So I will also import the likedContext and by using the likedContext, guess what happens. I can access the context values that we've set in the provider.

I can access the context values that we've set in the provider. So I'll grab both and before I save, let's verify the app is still broken, hard refresh, definitely broken. And now I'll hit save, revisit the app and check it out. No errors in the console, the UI is here, I can add Chase and I can add Russ and I can remove Frisket and Leah and everything still works again. But this time we've skipped the whole prop drilling,

and everything still works again. But this time we've skipped the whole prop drilling, passing the like state through the PuppyList, the PuppyCard and the likeToggle. Once again, I wouldn't necessarily do this change here, I would probably wait until there's a few more components that pass the same props down. Uh, and it's actually quite nice sometimes to have a paper trail, an explicit way of where the props are passed.

to have a paper trail, an explicit way of where the props are passed. But I want you to know about the context API and understand how it works. Alright, for the sake of completion, we also going to use the context to receive the like state in the short list. Again for learning purposes, I've broken my app because something is wrong now in the short list. But we will go inside the short list,

because something is wrong now in the short list. But we will go inside the short list, remove the props received and the types and the types import and down here because now we can't access liked. Instead what we'll do is const liked, setLiked equals use, not useContext, which is the previous way you could access the context in React, we are going to use the new use function and have the liked context passed to it.

React, we are going to use the new use function and have the liked context passed to it. So now we get a liked array of puppy IDs that is now happily fulfilling its duty done here. And if I save the app works again and if I refresh we shouldn't have any console errors and everything works. Alright. There's a couple of important things to understand about the context API. The first one is you cannot access a context value from a

to understand about the context API. The first one is you cannot access a context value from a component if you don't have a wrapper. The context provider at a higher level, let me demo this real quick. So our short list and our puppies list are using the context, but if I was to comment out the context wrapper or the provider, our app is going to break again and you can see that the error message is somewhat useful.

Building useLiked Hook8:09

or the provider, our app is going to break again and you can see that the error message is somewhat useful but not as direct as it could be. And so I'll show you now a technique that can help users. You cannot prevent them from trying to access context and have this error, but we can at least provide a much more meaningful error that should help them fix the problem much quicker. Alright, so back to my liked context file here I will export a second thing, a function called useLiked.

Alright, so back to my liked context file here I will export a second thing, a function called useLiked. Hmm, interesting. This function name sort of makes it sound like a react hook and well it is, it is a custom react hook. That's right. We are going to build our first custom react hook here. So it's just a function that starts with the word use and then it'll have the same rules of hooks that you've learned about for useState.

and then it'll have the same rules of hooks that you've learned about for useState. So here we're going to create a useLiked custom hook that is going to consume the context, return the value and give some error messaging that makes more sense if there is an error. Alright, so check this out in here. We'll first grab the context const context and we'll do this exactly the same way we did in the ShortList and the LikeToggle components using the use function.

and we'll do this exactly the same way we did in the short list and the like toggle components using the use function and trying to access the liked context, which is just up here. Now, whenever React cannot find this context as a wrapper at a parent level element, it'll not be able to get its context. So we can check if there is no context and here we'll use copilot suggestion. We are going to throw an error.

and here we'll use Copilot suggestion. We are going to throw an error that has a meaningful message. So maybe something like the use liked hook must be used within a, uh, that's not how it's called liked context wrapper. Otherwise, if we do have the context will just, well return that context. So that's a surprisingly serviceable customer hook we've created here.

So that's a surprisingly serviceable customer hook we've created here. We can use it anywhere and then we don't have to import the use function or the like context wherever we use it. And then we have this meaningful useful error that should be more helpful than the one we were getting. So let's go in the ShortList component and check this out. I'm going to delete this and also delete the liked context and use imports.

I'm going to delete this and also delete the liked context and use imports. And instead I will use liked, which is the custom hook we've just created. So remember this was our error message about the short list cannot the structure property liked of use because we were trying to access a context value that wasn't present. Now if I refresh the page, check this out, our error is much nicer.

Now if I refresh the page, check this out, our error is much nicer. The use liked hook must be used within a linked context wrapper. If I read this, I'm instantly like, oh duh, of course I must have forgotten to have the wrapper and yep, I did. And if that is fixed, the error goes away and we are off to the races. Alright, very cool. So let's also go

and we are off to the races. Alright, very cool. So let's also go to our LikedToggle component and instead of using the useLike context, I will use the useLiked custom hook that we've created, which means I can remove the two imports and just import the hook and everything still works perfectly, but I just wanna make sure that something very important is understood here.

Context Rerender Caveat11:07

but I just wanna make sure that something very important is understood here. Whenever you have a context wrapper, a provider, every time that the data inside this context changes, every child of the context wrapper will re-render. Just like we've seen before when we set the states at the main component level, everything inside main re-render. Well if you have a context provider, this also happens. So even if you magically deep down a rabbit hole and reappear the other side,

So even if you magically deep down a rabbit hole and reappear the other side, whenever you consume that data on the other side, everything from the top level at the provider level will re-render. So I just wanna make sure that this is super clear because the context API is so cool and so easy to use that it's tempting to put all your states at the parent level and then just shove it in the context.

to put all your states at the parent level and then just shove it in the Context and you can just access it with a magic little hook everywhere you need it. Keep in mind that you're going to re-render everything that's inside the Context provider and that's the context API in a nutshell. I thought it was important to make a lesson on this. Like I said before, I do not wanna make these changes in our app.

Like I said before, I do not wanna make these changes in our app. So behind the scenes I'm going to roll back everything to where we were before, where we pass the liked and set liked stage through the components, through the puppies, this and the puppy yard. So I'll do this behind the scenes and I'll see you in the next video where we are going to do the search functionality, the filtering of the puppies.

to do the search functionality, the filtering of the puppies.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟