1 00:00:00,995 --> 00:00:01,980 - Now the last hook that I want to talk about 2 00:00:01,980 --> 00:00:03,450 inside of React and TypeScript 3 00:00:03,450 --> 00:00:05,220 is going to be the use context hook. 4 00:00:05,220 --> 00:00:07,170 And this one requires quite a bit of setup 5 00:00:07,170 --> 00:00:09,930 just because of the way the use context hook works. 6 00:00:09,930 --> 00:00:11,100 So the very first thing you'll notice 7 00:00:11,100 --> 00:00:13,320 if we have this code here, everything's working fine, 8 00:00:13,320 --> 00:00:15,750 but I get one error right here and it's essentially saying 9 00:00:15,750 --> 00:00:17,580 that it's expecting a default value. 10 00:00:17,580 --> 00:00:20,070 And that's because create context always expects you 11 00:00:20,070 --> 00:00:22,110 to pass in a default value. 12 00:00:22,110 --> 00:00:24,840 But oftentimes you don't have a default value. 13 00:00:24,840 --> 00:00:26,400 If you're creating a theme context 14 00:00:26,400 --> 00:00:29,100 you can obviously pass in a default value of dark mode, 15 00:00:29,100 --> 00:00:31,200 for example, but oftentimes your context 16 00:00:31,200 --> 00:00:32,910 is a lot more confusing than this. 17 00:00:32,910 --> 00:00:35,490 In our case, our context is getting an array of users. 18 00:00:35,490 --> 00:00:38,280 So what we could do is we could pass in and say 19 00:00:38,280 --> 00:00:41,310 that our users by default are going to be an empty array. 20 00:00:41,310 --> 00:00:42,870 But let's say that we did not want 21 00:00:42,870 --> 00:00:45,060 to pass in a default value for our users. 22 00:00:45,060 --> 00:00:47,190 We want it to be a little bit more complicated 23 00:00:47,190 --> 00:00:49,200 because it involves a little bit more data. 24 00:00:49,200 --> 00:00:51,090 Oftentimes what you're gonna do is you're just gonna 25 00:00:51,090 --> 00:00:53,580 pass in null as your default value because you want 26 00:00:53,580 --> 00:00:56,100 to be able to populate all your information inside of here. 27 00:00:56,100 --> 00:00:57,600 For example, maybe it's gonna be a bunch 28 00:00:57,600 --> 00:00:58,950 of different functions that you want, 29 00:00:58,950 --> 00:01:02,307 you wanna have an add user function and stuff like that. 30 00:01:02,307 --> 00:01:04,290 And you obviously can't define that up here. 31 00:01:04,290 --> 00:01:06,450 It must be defined inside of your component. 32 00:01:06,450 --> 00:01:09,000 So that makes it a little bit more tricky for you to do. 33 00:01:09,000 --> 00:01:10,650 For example, if we just create that function, 34 00:01:10,650 --> 00:01:12,237 we'll just say, "Add user." 35 00:01:13,347 --> 00:01:14,970 It's going to be a function, add a user. 36 00:01:14,970 --> 00:01:16,110 And this add user function, 37 00:01:16,110 --> 00:01:18,173 we'll just say it takes in a name. 38 00:01:18,173 --> 00:01:21,960 And what it's just going to do is just going to set users 39 00:01:21,960 --> 00:01:24,363 based on the users that we have previously. 40 00:01:25,800 --> 00:01:26,633 There we go. 41 00:01:28,260 --> 00:01:31,951 Return. And we're gonna get all of our previous users. 42 00:01:31,951 --> 00:01:33,150 And we want to add on a brand new user, 43 00:01:33,150 --> 00:01:36,180 so we'll get a random ID for them. 44 00:01:36,180 --> 00:01:37,170 There we go. 45 00:01:37,170 --> 00:01:38,670 Our name is going to be our name 46 00:01:38,670 --> 00:01:41,070 and also it should probably take in an age as well. 47 00:01:41,070 --> 00:01:42,870 That way they at least match all the same stuff. 48 00:01:42,870 --> 00:01:44,513 There we go. 49 00:01:44,513 --> 00:01:45,840 And this is going to take in a name, 50 00:01:45,840 --> 00:01:48,851 which is a string, and an age, which is a number. 51 00:01:48,851 --> 00:01:50,790 There we go. So obviously I can't do a default value. 52 00:01:50,790 --> 00:01:52,950 I could say that my user is gonna be an empty array, 53 00:01:52,950 --> 00:01:55,950 but I obviously can't define my add user section as well 54 00:01:55,950 --> 00:01:58,110 to be able to get that default value properly. 55 00:01:58,110 --> 00:02:00,090 So what I need to do is just pass in null. 56 00:02:00,090 --> 00:02:01,752 That's probably the best thing 57 00:02:01,752 --> 00:02:02,910 for us to do in this scenario. 58 00:02:02,910 --> 00:02:04,800 And then what we can do inside of here is we can define 59 00:02:04,800 --> 00:02:06,510 what we want the type for this to be. 60 00:02:06,510 --> 00:02:08,430 So we can create a type for our context. 61 00:02:08,430 --> 00:02:10,680 We'll just say "Context type." 62 00:02:10,680 --> 00:02:12,840 And we know that this is going to be a user array. 63 00:02:12,840 --> 00:02:14,880 So we can say we have a user array. 64 00:02:14,880 --> 00:02:16,920 And we need an add user function. 65 00:02:16,920 --> 00:02:20,880 And this add user function takes in a name and an age, 66 00:02:20,880 --> 00:02:24,120 which in our case is going to be a string, 67 00:02:24,120 --> 00:02:27,960 and an age, which is a number, just like that. 68 00:02:27,960 --> 00:02:29,550 And then it's going to return to us nothing, 69 00:02:29,550 --> 00:02:31,800 so we can just keep the return type as void. 70 00:02:31,800 --> 00:02:33,510 There we go. That's our context type. 71 00:02:33,510 --> 00:02:35,820 Let's pass that in there for our create context. 72 00:02:35,820 --> 00:02:37,950 Also, since we're setting our default value to null, 73 00:02:37,950 --> 00:02:39,750 we need to make sure that we specify null here 74 00:02:39,750 --> 00:02:42,180 as the other type, so this context right here 75 00:02:42,180 --> 00:02:44,010 is a type of either our context type, 76 00:02:44,010 --> 00:02:46,560 which has all our information, or of null. 77 00:02:46,560 --> 00:02:48,035 So that's really good. 78 00:02:48,035 --> 00:02:49,491 And you'll notice now all of our code 79 00:02:49,491 --> 00:02:50,324 inside of here is working fine. 80 00:02:50,324 --> 00:02:51,990 So really the only thing you need to do when you're creating 81 00:02:51,990 --> 00:02:54,690 your context is you need to give it a generic type you want 82 00:02:54,690 --> 00:02:56,400 and you need to give it a default value. 83 00:02:56,400 --> 00:02:57,780 And if it doesn't make sense for you 84 00:02:57,780 --> 00:02:59,520 to supply a default value, for example, 85 00:02:59,520 --> 00:03:01,350 if you have functions and stuff you're defining, 86 00:03:01,350 --> 00:03:03,780 my recommendation is just pass in null and then 87 00:03:03,780 --> 00:03:05,130 just make sure you can have it optionally 88 00:03:05,130 --> 00:03:06,480 be null as the other type. 89 00:03:06,480 --> 00:03:08,220 So now it's either going to be our type 90 00:03:08,220 --> 00:03:09,870 or it's going to be null. 91 00:03:09,870 --> 00:03:10,800 Now the one problem, though, 92 00:03:10,800 --> 00:03:12,851 is this doesn't solve all of our errors. 93 00:03:12,851 --> 00:03:13,920 If we go here to where we're using this, 94 00:03:13,920 --> 00:03:15,030 you'll notice here we're getting an error 95 00:03:15,030 --> 00:03:16,500 because users does not exist 96 00:03:16,500 --> 00:03:18,780 on the type of context type or null. 97 00:03:18,780 --> 00:03:20,790 And that's because it could be null. 98 00:03:20,790 --> 00:03:23,520 And in our case, if it's null, obviously there's no users. 99 00:03:23,520 --> 00:03:25,710 So generally what I like to do when I'm using context 100 00:03:25,710 --> 00:03:27,480 is I like to create a custom hook. 101 00:03:27,480 --> 00:03:29,070 So we can just call this hook whatever we want. 102 00:03:29,070 --> 00:03:30,870 We'll call it "Function use." 103 00:03:30,870 --> 00:03:32,700 And I generally, I'll say like use users, 104 00:03:32,700 --> 00:03:34,560 if that's what we're doing in our case. 105 00:03:34,560 --> 00:03:36,990 And then I no longer need to export my actual context 106 00:03:36,990 --> 00:03:40,440 because here this hook is going to call use context 107 00:03:40,440 --> 00:03:43,170 and it's going to pass in my context just like this. 108 00:03:43,170 --> 00:03:45,933 And that's going to give me my user's context. 109 00:03:47,460 --> 00:03:49,350 And you may think, "Well, I'll just return that as is." 110 00:03:49,350 --> 00:03:52,080 But the problem, again, is that this can be null. 111 00:03:52,080 --> 00:03:54,600 So what I wanna do is I wanna just do a really quick check 112 00:03:54,600 --> 00:03:58,290 to see if my user's context is equal to null. 113 00:03:58,290 --> 00:03:59,670 'Cause if it is equal to null, 114 00:03:59,670 --> 00:04:01,560 well, now I can just throw some type of error. 115 00:04:01,560 --> 00:04:03,423 So I'll say "Throw new error. 116 00:04:05,160 --> 00:04:10,160 Must use within provider." 117 00:04:13,620 --> 00:04:14,670 There we go. 118 00:04:14,670 --> 00:04:17,760 And then down here below that I can return my user context. 119 00:04:17,760 --> 00:04:20,100 So now if I look at this, the type of this down here 120 00:04:20,100 --> 00:04:23,070 is actually just my context type because I check to see 121 00:04:23,070 --> 00:04:25,980 if it's null, don't let me return it at all. 122 00:04:25,980 --> 00:04:29,103 So now if I use this use users hook instead, 123 00:04:30,953 --> 00:04:33,030 just like this, make sure I import that properly, 124 00:04:33,030 --> 00:04:34,983 get rid of all these imports up here. 125 00:04:37,426 --> 00:04:39,630 Make sure I actually export it from here so I can import it. 126 00:04:39,630 --> 00:04:41,130 There we go. 127 00:04:41,130 --> 00:04:42,960 And now if I try to import that you'll notice 128 00:04:42,960 --> 00:04:45,840 all my errors go away, because now this user type is defined 129 00:04:45,840 --> 00:04:47,070 because this is returning to me 130 00:04:47,070 --> 00:04:49,500 whatever my context type is in my case. 131 00:04:49,500 --> 00:04:51,660 So again, to kind of reiterate what we've done here, 132 00:04:51,660 --> 00:04:54,150 is essentially we've said. "Okay, we created our context 133 00:04:54,150 --> 00:04:56,460 and we specified the exact type we want it to be." 134 00:04:56,460 --> 00:04:58,110 But since we need to pass it a default type 135 00:04:58,110 --> 00:04:59,993 we're gonna say, "You know what? 136 00:04:59,993 --> 00:05:01,654 By default we're gonna set this as a null." 137 00:05:01,654 --> 00:05:04,320 And that means if we try to use this context somewhere else 138 00:05:04,320 --> 00:05:05,970 where it's not wrapped inside a provider, 139 00:05:05,970 --> 00:05:07,950 'cause if we wrap it inside of a provider, 140 00:05:07,950 --> 00:05:09,570 the provider always has a value. 141 00:05:09,570 --> 00:05:12,690 It'll never be null if it's inside of a provider. 142 00:05:12,690 --> 00:05:15,300 So this will obviously never be true if we're in a provider 143 00:05:15,300 --> 00:05:17,940 and it'll just return our context with the correct type. 144 00:05:17,940 --> 00:05:20,340 But if for some reason our child is rendered 145 00:05:20,340 --> 00:05:22,980 outside of our provider, well, now if we make sure 146 00:05:22,980 --> 00:05:27,390 we just wrap this properly, there we go. 147 00:05:27,390 --> 00:05:28,590 Now we're actually going to get an error. 148 00:05:28,590 --> 00:05:30,300 And if I inspect my page, go to the console, 149 00:05:30,300 --> 00:05:32,640 we'll essentially get an error, "Must use within provider." 150 00:05:32,640 --> 00:05:35,700 And that's because again, this is returning to us null 151 00:05:35,700 --> 00:05:36,960 because we're not in the provider. 152 00:05:36,960 --> 00:05:38,010 So it has no value. 153 00:05:38,010 --> 00:05:40,312 So our user context is set 154 00:05:40,312 --> 00:05:41,145 to the default value, which is null. 155 00:05:41,145 --> 00:05:43,110 So that's what this check right here allows us to do. 156 00:05:43,110 --> 00:05:45,270 Obviously, though, if we want to have this in the provider, 157 00:05:45,270 --> 00:05:47,070 which is what's going to happen most of the time, 158 00:05:47,070 --> 00:05:48,840 it's not going to be null, which means 159 00:05:48,840 --> 00:05:50,970 it'll just return to you your user context. 160 00:05:50,970 --> 00:05:53,310 And since we put this check here, it's going to make sure 161 00:05:53,310 --> 00:05:54,960 that it's never null inside your type. 162 00:05:54,960 --> 00:05:56,640 'Cause we already checked to see if it's null, 163 00:05:56,640 --> 00:05:58,200 which means when you actually use it 164 00:05:58,200 --> 00:06:00,960 you don't have to worry about that null error check at all. 165 00:06:00,960 --> 00:06:03,090 This is really nice because now you can use your context 166 00:06:03,090 --> 00:06:05,010 and just assume everything is going to be there, 167 00:06:05,010 --> 00:06:06,030 which is really great. 168 00:06:06,030 --> 00:06:08,460 And over here, inside of your actual code 169 00:06:08,460 --> 00:06:10,350 you're doing all the different null checks and stuff 170 00:06:10,350 --> 00:06:12,252 that you need to to make sure that 171 00:06:12,252 --> 00:06:13,470 your actual consuming code is able to consume it 172 00:06:13,470 --> 00:06:15,870 without dealing with all that behind the scenes.