-
-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hooks with Typescript: ts(2339) Property 'handleClickOutside' does not exist. #310
Comments
try this in the same file:
|
thanks for the tip 👍 |
I tried this solution but typescript complains this:
|
I also tried it and I get |
Third on the train, the create-react-app default linter doesn't like it
not an error, but if someone could suggest an alternative solution, would be great. |
As a solution you can get rid of this library and use this small hook from https://usehooks.com/useOnClickOutside/. It works for me really well: import { useState, useEffect, useRef } from 'react';
// Usage
function App() {
// Create a ref that we add to the element for which we want to detect outside clicks
const ref = useRef();
// State for our modal
const [isModalOpen, setModalOpen] = useState(false);
// Call hook passing in the ref and a function to call on outside click
useOnClickOutside(ref, () => setModalOpen(false));
return (
<div>
{isModalOpen ? (
<div ref={ref}>
👋 Hey, I'm a modal. Click anywhere outside of me to close.
</div>
) : (
<button onClick={() => setModalOpen(true)}>Open Modal</button>
)}
</div>
);
}
// Hook
function useOnClickOutside(ref, handler) {
useEffect(
() => {
const listener = event => {
// Do nothing if clicking ref's element or descendent elements
if (!ref.current || ref.current.contains(event.target)) {
return;
}
handler(event);
};
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
return () => {
document.removeEventListener('mousedown', listener);
document.removeEventListener('touchstart', listener);
};
},
// Add ref and handler to effect dependencies
// It's worth noting that because passed in handler is a new ...
// ... function on every render that will cause this effect ...
// ... callback/cleanup to run every render. It's not a big deal ...
// ... but to optimize you can wrap handler in useCallback before ...
// ... passing it into this hook.
[ref, handler]
);
} |
Thanks for the hooks @BoGeM ;) For those looking for an external solution I would recommend https://github.com/airbnb/react-outside-click-handler |
Defining the handler on the function after its definition worked for me. I think it's ok, as its value will be set on rendering the component anyways. import {useState} from 'react'
import onClickOutside from 'react-onclickoutside'
const UserInfo = () => {
const [menuVisible, setMenuVisible] = useState(false)
UserInfo.clickOutside = () => setMenuVisible(false)
return (
<div className="cursor-pointer"
onClick={() => setMenuVisible(!menuVisible)}
>
<p>Click me</p>
<div className={!menuVisible && 'hidden'}>
<p>I am zee menu</p>
<p>I am zee menu</p>
</div>
</div>
)
}
UserInfo.clickOutside = null /// !! this
export default onClickOutside(UserInfo, {
handleClickOutside: () => UserInfo.clickOutside,
}) |
Just a note: if you've already written the code to make hooks work, PRs that add a hook solution are most certainly welcome, and I'll be more than happy to push out a new version. |
Update: Another thing I noticed with this pattern is that when you have multiple instances of the same Component, only the last one triggers handleClickOutside.
Here is my code, grossly simplified (sorry if it is more of a TS question rather than this library, but in any way it would be nice to see an example).
error: Property 'handleClickOutside' does not exist on type '({ options, }: Props) => Element'. ts(2339)
The code works fine but in the editor Dropdown.handleClickOutside lines highlights this error.
Other than using // @ts-ignore, how can I solve this issue? how can I specify the property?
The text was updated successfully, but these errors were encountered: