0

I have a sidebar function to close on a click outside, however I am getting a TypeError: Property 'contains' does not exist on type 'never'.

const sidebar = useRef(null);
  const trigger = useRef(null);

  // Close on click outside
  useEffect(() => {
    const clickHandler = ({ target }: { target: ReactNode }) => {
      if (!sidebar.current || !trigger.current) return;
      if (
        !sidebarOpen ||
        sidebar.current.contains(target) || // Error: Property 'contains' does not exist on type 'never'.
        trigger.current.contains(target)
      )
        return;
      setSidebarOpen(false);
    };
    document.addEventListener('click', clickHandler);
    return () => document.removeEventListener('click', clickHandler);
  });
Gravy59
  • 67
  • 2
  • 5
  • ...nothing? If you don't need an initial value, simply don't add one. However, if you're getting an error, and you don't show the error, no one has any reason to believe you're getting an error. Remember to put [all the details about your question in your question](/help/how-to-ask) =) – Mike 'Pomax' Kamermans Dec 13 '21 at 18:28
  • @Mike'Pomax'Kamermans I have updated the question. – Gravy59 Dec 13 '21 at 18:47
  • No, show the _actual_ error: just like code, it's important to show the true error text and relations to the code, so copy-paste it (including the stack trace) and then put that in your post with code formatting =) – Mike 'Pomax' Kamermans Dec 13 '21 at 18:48

2 Answers2

1

You can use a generic argument with useRef e.g.

const sidebar = useRef<HTMLElement | null>(null);

And now you will be able to use optional chaining e.g. sidebar.current?.contains

basarat
  • 261,912
  • 58
  • 460
  • 511
0

I guess you aren't using typescript. If you were, it would have been easier with a simple not null assertion. Like these:

As you don't have that, you should try something like this:

if(a){//check if `a` is undefined or not, if not then
   console.log(a.b)
   if(a.b){//check if the property in `b` in `a` is defined or not, if defined then
      console.log(a.b.c)
   }
}

It might be confusing at first that, we are checking for a is undefined or not and using a.b? Yes, we are. Even if a si defined and b in a is not. We may not need to worry. As for the worst case, that will give us undefined. But attribute inside undefined, is an error.

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86
  • 2
    Note that modern JS (and thus modern TS) has [optional chaining syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining) for this. `if (a?.b?.c) { ... }` in this case. – Mike 'Pomax' Kamermans Dec 13 '21 at 18:49