A lightweight React hook that detects clicks outside elements and triggers a callback. Can also detect keypresses.
📈 Over 7,600 weekly users (as of June 2022).
👍 Great for toggling dropdowns!
Notice: This package is looking for maintainers! Due to my professional and personal commitments, I don't have a whole lot of time to devote to maintaining this library. Some users have pointed out a few issues in the Github repo - feel free to take a stab at them!
- 🖱 💻 Detects clicks outside an element and/or keypresses.
- 🔨 Customizable: disable clicks, disable keypresses, or specify keys that will trigger the callback
- 🎣 Built with React hooks
- 🔥 Written in TypeScript
Install with Yarn:
yarn add react-detect-click-outside
Or with NPM:
npm i react-detect-click-outside
Import into your component like so:
import { useDetectClickOutside } from 'react-detect-click-outside';
Here's an example of how to use the hook.
This library was built with UI features like dropdowns in mind. Below is a quick and functioning example of how to include it in a dropdown component:
const Dropdown = ({ closeDropdown }) => {
const ref = useDetectClickOutside({ onTriggered: closeDropdown });
return (
<div className="dropdown" ref={ref}>
<p>This is a dropdown!</p>
</div>
);
};
How to implement the hook inside a function component:
- Assign the hook to a variable before the component's return statement (above we use
ref
). Pass an empty object into the hook as an argument.
const ref = useDetectClickOutside({});
-
The object you just passed into the
useDetectClickOutside
hook requires a property calledonTriggered
. The value ofonTriggered
must be a function — by default, it'll be called anytime a user clicks outside the component or hits theEscape
key.In the example above, we used a function called
closeToggle
. This function is passed down from a parent component (let's call itContainer
) and controls a piece of state that determines whether theDropdown
component is visible.Here's a quick, trimmed-down example:
const Container = () => { const [displayDropdown, setDisplayDropdown] = useState(false); const closeDropdown = () => { setDisplayDropdown(false); } return ( { displayDropdown && <Dropdown/> } ) }
Now, go ahead and pass your callback into the
useDetectClickOutside
hook!const ref = useDetectClickOutside({ onTriggered: closeDropdown });
- Assign your
ref
constant (or whatever constant you assigned theuseDetectClickOutside
hook to) as a ref to the outermost element returned by your target component.
return ( <div className="dropdown" ref={ref}> <p>This is a dropdown!</p> </div> );
Here's what the whole component should look like now:
const Dropdown = ({ closeDropdown }) => { const ref = useDetectClickOutside({ onTriggered: closeDropdown }); return ( <div className="dropdown" ref={ref}> <p>This is a dropdown!</p> </div> ); };
Congrats! Your
useDetectClickOutside
should now trigger anytime a user clicks outside your component or presses theEscape
key.Want to customize your hook? Check out some of the additional options below.
- Assign your
The object passed into the useDetectClickOutside
hook accepts the following properties. Note that only onTriggered
is required.
A callback function, e.g. one that toggles the visibility of the component. By default, this function is triggered by a click outside the component, and by an Escape
keyup event.
Example:
const ref = useDetectClickOutside({ onTriggered: closeDropdown });
When passed to the hook, this option will prevent clicks from triggering the onTriggered
callback when the component is in the DOM. This option is disabled by default.
Example:
const ref = useDetectClickOutside({
onTriggered: closeDropdown,
disableClick: true,
});
When passed to the hook, this option will prevent touch events from triggering the onTriggered
callback when the component is in the DOM. This option is disabled by default.
Example:
const ref = useDetectClickOutside({
onTriggered: closeDropdown,
disableTouch: true,
});
This option will prevent keypresses from triggering the onTriggered
callback when the component is in the DOM. This option is disabled by default.
Example:
const ref = useDetectClickOutside({
onTriggered: closeDropdown,
disableKeys: true,
});
This option will let any keypress trigger the onTriggered
callback when the component is in the DOM - not just the Escape
key. This option is disabled by default.
Example:
const ref = useDetectClickOutside({
onTriggered: closeDropdown,
allowAnyKey: true,
});
An array of key values that will trigger the onTriggered
callback.
Example:
const ref = useDetectClickOutside({
onTriggered: closeDropdown,
triggerKeys: ['Enter', 'Tab', 'x'],
});
Note: This option overrides the default hook behavior of triggering the onTriggered
callback with the Escape
key. If you still wish to trigger the onTriggered
function with Escape
, you need to add it to the array (e.g. triggerKeys=['Escape', 'Enter']
).
You must be using React 16.8.0 or later. In other words, your version of React must support hooks.