1 00:00:01,250 --> 00:00:04,700 Before we move on, there's one last thing I want to show you around this drop down component. 2 00:00:05,330 --> 00:00:07,220 I can open up my app James File. 3 00:00:07,400 --> 00:00:08,180 Here it is right here. 4 00:00:08,300 --> 00:00:09,740 I'm looking at the app component. 5 00:00:10,310 --> 00:00:15,470 We're going to add in a little bit of code to this thing very quickly to toggle the visibility of the 6 00:00:15,470 --> 00:00:16,940 dropdown component entirely. 7 00:00:17,180 --> 00:00:20,240 So when I say toggle, I'm not talking about opening or closing the dropdown. 8 00:00:20,480 --> 00:00:23,420 I'm talking about whether or not we show the drop down at all. 9 00:00:23,840 --> 00:00:25,190 We're going to add this code in very quickly. 10 00:00:25,290 --> 00:00:29,120 And then as soon as we do, we're going to start to see a really mysterious error message start to appear. 11 00:00:29,930 --> 00:00:35,780 OK, so I'm going to add in a new piece of state inside the app component called Show DropDown, and 12 00:00:35,780 --> 00:00:37,120 I'll get a setter for that as well. 13 00:00:39,960 --> 00:00:43,620 And I'll default that to be a value of true, which means that I do want to show the dropdown. 14 00:00:44,580 --> 00:00:47,310 Then right about the drop down itself, I can add in a button. 15 00:00:48,430 --> 00:00:51,050 But the text of Tuggle dropped down. 16 00:00:53,210 --> 00:00:55,910 On the button, I'm going to add in on click event listener. 17 00:00:57,520 --> 00:01:01,960 So whenever someone calls on this thing, we're going to flip the value of show, drop down to the opposite 18 00:01:01,990 --> 00:01:03,220 of whatever it currently is. 19 00:01:03,740 --> 00:01:09,580 So inside that arrow function right there, we will call set show dropdown and then pass in the opposite. 20 00:01:10,570 --> 00:01:11,720 Of show down. 21 00:01:13,130 --> 00:01:18,540 And then finally, I'm going to wrap the drop down right here with a set of curly braces. 22 00:01:24,350 --> 00:01:28,810 And inside the curly braces, we're going to take a look at the show dropped down. 23 00:01:29,510 --> 00:01:32,950 He said, state, if that is true, then I want to show the drop down. 24 00:01:32,970 --> 00:01:38,100 So notice I got to put in a question mark right here for a ternary expression and a show dropped on 25 00:01:38,100 --> 00:01:38,790 his false. 26 00:01:38,910 --> 00:01:41,580 I'll put in a colon and then no. 27 00:01:41,670 --> 00:01:43,080 Which means display nothing at all. 28 00:01:43,980 --> 00:01:48,140 All we're doing here is toggling the visibility or the existence of the dropdown entirely. 29 00:01:48,510 --> 00:01:48,670 OK. 30 00:01:48,840 --> 00:01:50,610 Let's now save this and tested out. 31 00:01:52,060 --> 00:01:53,860 I see the drop down by default, which is good. 32 00:01:54,130 --> 00:01:55,690 I can still open and close it. 33 00:01:56,080 --> 00:01:56,490 Open it. 34 00:01:57,350 --> 00:02:00,000 Like off screen, everything still works as expected. 35 00:02:00,360 --> 00:02:01,380 But take a look at this. 36 00:02:01,830 --> 00:02:05,940 If I click on toggle dropdown, the dropdown goes away again as expected. 37 00:02:06,420 --> 00:02:11,400 And now if I click anywhere else on the screen, we get a really nasty error message. 38 00:02:11,940 --> 00:02:13,110 So what's going on here? 39 00:02:13,920 --> 00:02:16,290 Well, let's take a careful look at the error message itself. 40 00:02:16,320 --> 00:02:19,500 It says cannot read property contains of No. 41 00:02:20,070 --> 00:02:22,680 And it's pointing out some code inside of our event. 42 00:02:22,680 --> 00:02:23,130 Listener. 43 00:02:24,000 --> 00:02:24,180 All right. 44 00:02:24,210 --> 00:02:25,020 Let's look back over. 45 00:02:26,130 --> 00:02:31,330 And take a look at that inside of our body event listener right here inside of our dropdown Dodgiest 46 00:02:31,410 --> 00:02:31,740 file. 47 00:02:32,580 --> 00:02:39,330 So the air message is saying that refought current is evaluating to know, as it says we are trying 48 00:02:39,330 --> 00:02:41,190 to call it, property contains on. 49 00:02:41,250 --> 00:02:46,140 No, the report current is null instead of a reference to a DOM element, as we would expect. 50 00:02:46,830 --> 00:02:48,210 So what exactly is happening? 51 00:02:48,780 --> 00:02:54,960 Well, whenever we remove a component from the DOM, all the refs that are attached to elements inside 52 00:02:54,960 --> 00:03:00,000 that component get set to note where more specifically the refought current property gets set to null 53 00:03:00,210 --> 00:03:02,580 because we no longer have an element to refer to. 54 00:03:03,120 --> 00:03:04,380 Remember this ref right here? 55 00:03:05,010 --> 00:03:08,040 We are assigning to the top level element inside of our component. 56 00:03:08,790 --> 00:03:13,470 So if that element right there is removed and the dumb ref current gets set to null because there is 57 00:03:13,470 --> 00:03:15,540 no longer an element for us to refer to. 58 00:03:16,560 --> 00:03:22,800 However, we still have this event listener set up this event, listeners still going to run whenever 59 00:03:22,800 --> 00:03:24,460 we click on something inside the dumb. 60 00:03:25,410 --> 00:03:29,300 So whenever we click on something Refco Current evaluates to know. 61 00:03:29,820 --> 00:03:32,130 We then tried to call it a contains property on that. 62 00:03:32,520 --> 00:03:36,630 And, well, we end up with that error message saying cannot refer to contains on known. 63 00:03:38,170 --> 00:03:39,130 How are we going to fix this? 64 00:03:39,760 --> 00:03:44,170 Well, what we really need to do here is make sure that whenever we are about to remove the drop down 65 00:03:44,170 --> 00:03:48,100 component from the dam, we should turn off this event listener. 66 00:03:48,880 --> 00:03:52,660 So to do so, we're going to make use of that cleanup function from use effect. 67 00:03:52,720 --> 00:03:57,520 Once again, remember that we can return a function from USIE effect. 68 00:03:58,620 --> 00:04:02,920 And this will be called right before the next time that this function is called. 69 00:04:03,520 --> 00:04:07,000 There's one other scenario when this clean up function is going to be invoked. 70 00:04:07,030 --> 00:04:11,560 And that is whenever we are about to stop showing the entire drop down component on the screen. 71 00:04:12,510 --> 00:04:17,850 So if we are about to remove the drop down component entirely, this cleanup function will also be invoked. 72 00:04:18,570 --> 00:04:23,160 That makes this a great location to do any kind of cleanup for the entire component that we want to 73 00:04:23,160 --> 00:04:24,810 do instead of here. 74 00:04:24,870 --> 00:04:29,570 Well, we really want to do is make sure that we do not attempt to call this event listener anymore. 75 00:04:29,760 --> 00:04:34,080 We really want to detach or remove this event listener from the body element entirely. 76 00:04:34,800 --> 00:04:39,000 And that's exactly what we're going to do to make sure that we remove this event. 77 00:04:39,000 --> 00:04:39,420 Listener. 78 00:04:39,570 --> 00:04:42,040 We're going to first kind of massage the code we have inside of your. 79 00:04:42,090 --> 00:04:42,690 A little bit. 80 00:04:43,410 --> 00:04:45,840 We're gonna take the callback itself. 81 00:04:46,290 --> 00:04:50,440 So that's the event right there all the way down to the bottom of set open. 82 00:04:51,270 --> 00:04:55,350 We will cut that and assign it to a new variable right above. 83 00:04:56,010 --> 00:04:56,730 Hold on. 84 00:04:56,880 --> 00:04:57,900 Body click. 85 00:04:59,790 --> 00:05:01,050 And I'll paste in that function. 86 00:05:02,850 --> 00:05:07,490 We can then provide on body click as the callback to the body click event listener. 87 00:05:10,500 --> 00:05:14,510 And then finally, inside of our cleanup function, we're going to make sure that whenever our components 88 00:05:14,510 --> 00:05:17,820 are about to be removed from the DOM, we remove that callback entirely. 89 00:05:18,840 --> 00:05:23,550 We'll do a document dump body remove event listener. 90 00:05:26,040 --> 00:05:30,860 Now, let's say that we want to remove an event listener from the click event and a specific event listener 91 00:05:30,860 --> 00:05:33,830 we want to remove is the on body click function. 92 00:05:37,800 --> 00:05:42,890 So now, whenever our component is first rendered into the DOM, because we've got this array right 93 00:05:42,890 --> 00:05:47,300 here as the second argument, we're going to run the use effect function or the function we provide 94 00:05:47,300 --> 00:05:47,570 to it. 95 00:05:47,600 --> 00:05:51,380 Exactly one time at that point, we're going to setup the event listener. 96 00:05:52,070 --> 00:05:57,200 Then whenever our dropdown is about to be removed from the DOM, react is going to automatically call 97 00:05:57,230 --> 00:05:58,100 our cleanup function. 98 00:05:58,490 --> 00:05:59,960 And that's going to remove the event. 99 00:05:59,960 --> 00:06:01,670 Listener watching for that click. 100 00:06:02,970 --> 00:06:03,200 All right. 101 00:06:03,300 --> 00:06:05,440 Let's save this look back over. 102 00:06:07,040 --> 00:06:09,770 Now, I can still open the things tonight, I'm close at all. 103 00:06:09,800 --> 00:06:11,540 Everything is still working as expected. 104 00:06:12,500 --> 00:06:18,410 And if I toggled visibility the down, I can then click anywhere on the screen and I don't get any error 105 00:06:18,410 --> 00:06:19,040 messages. 106 00:06:20,540 --> 00:06:22,070 As soon as I show the drop down again. 107 00:06:22,430 --> 00:06:25,370 Well, it comes back up and I rebind that event. 108 00:06:25,370 --> 00:06:30,590 Listener So use effect runs once again, event listener gets set up again and I can still open the dropdown, 109 00:06:30,680 --> 00:06:32,810 click outside of it and see the thing close. 110 00:06:34,290 --> 00:06:34,500 All right. 111 00:06:34,560 --> 00:06:35,020 Well, that's it. 112 00:06:36,360 --> 00:06:38,400 Well, that was pretty much it for our drop down component. 113 00:06:38,550 --> 00:06:42,200 So we'll take a pause right here and continue on our next little widget in just a moment.