Click Outside to Close - React Hook

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today I want to show you how to build a click outside to close hook and the best show why I need this let's take a look at this drop down menu this is from telling you I and when I click this button the menu opens and when I click it it closes however if the menu is open and I come to some other part of the page and I click the menu stays open and I think most users would expect the menu to close once we click outside of it so this is what I want to do I want to wire up a hook to make this work correctly and here's how we've built that drop down menu we've got a single component and that component has some state is open and then we have this HTML that is our menu so here's our button and when you click the button we toggle is open and then if is open is true we're using react spring to animate the menu open and closed so that's how we get this nice animation when you click and toggle the menu so what we want to do is we want to use an effect to toggle this is open state to false when the user clicks outside the menu so let's go ahead and use effect and to start we're gonna do something really simple will do document add event listener and we'll use the mouse down event and when this is clicked well we'll set is open to false okay so I can click the button and I can show the menu and then I can come over here and I can click is open get set to false and the menu disappears alright so while this works there's a problem if I open the menu and I click an item in the menu well that most down eventhandler triggers and the menu closes so this is where the notion of click outside comes into play really we only want our effect to set is open a fall when we click outside of the area of this menu and we can accomplish that by using the event and we can say if the event target which is where the click actually happened is not in the menu then we can set as open a false so before we can continue we need to know more information about the menu the reason being we need to know where the menu is located so we can detect if the click happened inside or outside of it and we can get access to that information using a reference so let's come over to our menu and let's add a ref and we'll just call this menu ref for now and right before we create our effect we will say let menu F equals use rough ok so now we need to detect was the click outside of the menu and we're gonna use our menu ref so we'll say menu ref current contains event target and now if the events target is not inside of the menu ref then we will run our set is open to false all right let's see what this looks like so I can open my menu I can click outside it closes but if I open my menu and I start clicking in the menu it doesn't close and now if I click this options button well the menu closes all right this is looking good let's go ahead and let's be good citizens here and have our fact cleanup the event listener so you can do this by returning a function that runs when the component renders and this effect updates and here we want to document remove event listener and we're gonna move remove the mouse down event and we're gonna remove our handler and now we need to get a reference to this handler so we're gonna take this guy and put him into a variable so we'll say let handler equals this and then when the effect runs we will add the handler and when the effect cleans up we will remove the handler all right let's just double check and make sure this still works so I can click click outside click click a menu item and then click the button to toggle it back to closed now if we look at this code this works we're you know doing everything correctly here but this is a lot to read you know if I if I came into this component and I saw this code you know it's only 12 lines but it might take me a minute to figure out what's going on here you know the fact that we're using a mouse down event it's really an implementation detail of our strategy it doesn't really express what we're trying to do like why we're writing this code if you think about it you know if we could like snap our fingers and come up with ideal API it would be something like we have a hook use click use click outside and this thing would take a function that runs whenever you click outside so set is open to false this is pretty easy to follow what's going on when I click outside that is open to false now we need a ref here to attach to a Dom node so you could imagine our hook returning a ref or returning a Dom node to attach to the thing that you want to click outside of so I like this API I think it's it's expressive the intent is really clear and it hides all of its implementation details so let's go ahead and get this thing wired up I'm going to take our effect and I'm gonna move it outside of the component and I'm just gonna throw it at the top right here and now I'll say let use click outside is going to be a function that does all this stuff now if you remember our use click outside it takes something to do it takes a function to run when the user clicks outside so I'm gonna call this handler and it also it returns a ref so I'm also gonna grab this ref right here and move it into our hook and instead of calling it menu ref because this is a generic hook let's call it like Dom node just call it Dom node and this will return domnode okay and then instead of using many ref will champ update this to be domnode and then now we need to deal with the past in handler so we're shadowing handle are here we've got two handlers so I'm just going to change this one to be called maybe handler and the way that maybe handler is gonna work is it's gonna check to make sure that the event is outside of the the Dom node and if it is well it's gonna run the past in handler all right let's see what this looks like ah so we've got a bug here menu ref is not defined and what happened was is down in our component I rename the ref so the ref is now a generic name it's called Dom node and so we're just gonna update the ref where that we're passing into the actual menu HTML element so click the button the menu opens I can click outside of the menu the menu closes click the button start clicking items the menu stays open and then I can click the button again to toggle the menu so this is pretty cool we've got a hook that hides all of its implementation details and it's pretty straightforward when we click outside or setting is open false hopefully this video taught you how I like to think about hooks how I like to make my hooks expressive and how I like to hide all the implementation details inside the hook and I think what we came up with here is pretty nice
Info
Channel: Ryan Toronto
Views: 15,972
Rating: undefined out of 5
Keywords:
Id: eWO1b6EoCnQ
Channel Id: undefined
Length: 9min 14sec (554 seconds)
Published: Mon Apr 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.