HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptTip

React useClickOutside and useClickInside hooks

Submitted by: @import:30-seconds-of-code··
0
Viewed 0 times
useclickoutsidehooksanduseclickinsidereact

Problem

Handling click events in React is usually as simple as adding an onClick handler to a component. However, there are cases where you need to handle clicks outside or inside a component. This takes some extra effort and, most often than not, requires the use of custom hooks.
> [!NOTE]
>
> It's highly recommended that you learn more about detection of click events outside an element with JavaScript.
In order to handle clicks outside of a component, you'll first need to have a reference to the component. This is where the useRef() hook comes in handy. You can then use the useEffect() hook to add an event listener to the document and check if the click event occurred outside the component.

Solution

const useClickOutside = (ref, callback) => {
  const handleClick = e => {
    if (ref.current && !ref.current.contains(e.target)) {
      callback();
    }
  };
  React.useEffect(() => {
    document.addEventListener('click', handleClick);

    return () => {
      document.removeEventListener('click', handleClick);
    };
  });
};


>
> It's highly recommended that you learn more about detection of click events outside an element with JavaScript.
In order to handle clicks outside of a component, you'll first need to have a reference to the component. This is where the useRef() hook comes in handy. You can then use the useEffect() hook to add an event listener to the document and check if the click event occurred outside the component.
Using the hook is fairly simple. You just need to pass a ref and a callback function to handle the click event. The callback function will be called when the click event occurs outside the component.
Similarly, you can create a hook to handle clicks inside a component. The logic is almost the same, but you need to check if the click event occurred inside the component. This hook can come in handy when you need to handle clicks on multiple children and you don't want to add an onClick handler to each of them.
Again, you will need to pass the ref and a callback function to handle the click event inside the component, same as before.

Code Snippets

const useClickOutside = (ref, callback) => {
  const handleClick = e => {
    if (ref.current && !ref.current.contains(e.target)) {
      callback();
    }
  };
  React.useEffect(() => {
    document.addEventListener('click', handleClick);

    return () => {
      document.removeEventListener('click', handleClick);
    };
  });
};
const ClickBox = ({ onClickOutside }) => {
  const clickRef = React.useRef();
  useClickOutside(clickRef, onClickOutside);

  return (
    <div
      className="click-box"
      ref={clickRef}
      style={{
        border: '2px dashed orangered',
        height: 200,
        width: 400,
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center'
      }}
    >
      <p>Click out of this element</p>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <ClickBox onClickOutside={() => alert('click outside')} />
);
const useClickInside = (ref, callback) => {
  const handleClick = e => {
    if (ref.current && ref.current.contains(e.target)) {
      callback();
    }
  };
  React.useEffect(() => {
    document.addEventListener('click', handleClick);
    return () => {
      document.removeEventListener('click', handleClick);
    };
  });
};

Context

From 30-seconds-of-code: use-click-outside-inside

Revisions (0)

No revisions yet.