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>
);
}