Home > other >  Alternatives ways to check If I click inside or outside a box in react?
Alternatives ways to check If I click inside or outside a box in react?

Time:11-22

I need to check if user clicks inside or outside a certain area. In detail I need to know if I click on a react-select or on any other component. I found out I could do it in the following way:

  if (typeof window !== 'undefined') {
    window.addEventListener('click', function (e: any) {
      const boxId = e.target?.id;
      if (boxId === labelId) {
        //isClicking inside the box
        setIsFocusing(true);
      } else {
        //isClicking outside the box
        setIsFocusing(false);
      }
    });
  }

boxId contains the id of the component you are clicking on. So this could be the solution.

My actual problem is that apparently I can't set an Id to the react-select component even if the official doc says you can through the classical way, which means giving the id prop to the component.

In this sandbox I did two examples. One with a basic select and one with react-select. The basic one works how it is supposed to. I click on a label, the select appears and then you can select. When you click outside then it disappears and visualize the label. Can't do that with react-select because I can't set an ID to it.

Actually can't do it with onClick or onFocus because I can't check if I click outside.

How do you think I could solve this problem?

CodePudding user response:

Rather than creating a seperate window level listener, you can leverage the methods/events provided by the component to achieve this.

The react-select component will already close on clicking outside and provides an onMenuClose event that you listen for and set your state accordingly. I've included a useEffect to assign focus to the select when the focus state changes as it won't register the click outside unless focused, but you can find a more elegant solution in the context of your project as need be.

Here's a quick example sandbox

export default function App() {
  const [isFocusingReactSelect, setIsFocusingReactSelect] = useState(false);

  const selectRef = useRef();

  useEffect(() => {
    if (isFocusingReactSelect) {
      selectRef.current.focus();
    }
  }, [isFocusingReactSelect]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>show select based on where you click</h2>
      <div style={{ width: "100%", height: 200 }}>
        {!isFocusingReactSelect ? (
          <div
            style={{
              backgroundColor: "gray",
              width: "100%",
              height: 40,
              cursor: "pointer"
            }}
            onClick={() => setIsFocusingReactSelect(true)}
          >
            <p>react-select</p>
          </div>
        ) : (
          <Select
            ref={selectRef}
            options={options}
            closeMenuOnSelect={false}
            onMenuClose={() => setIsFocusingReactSelect(false)}
          />
        )}
      </div>
    </div>
  );
}
  • Related