Uncaught TypeError: невозможно прочитать свойство 'contains', равное null, в HTMLDocument.handler

В моем компоненте заголовка есть следующий код. Я подумал, что это может вызвать эту ошибку, потому что я пытаюсь получить к нему доступ еще до того, как он отобразится на экране. Я не уверен, почему это не работает. Я попытался использовать forwardRef в дочернем компоненте и получил следующую ошибку в справке из компонента SearchDropDown. Надеюсь, кто-нибудь может сказать мне, что здесь не так.

Type '((instance: unknown) => void) | MutableRefObject<unknown>' is not assignable to type 'LegacyRef<HTMLDivElement>'.
  Type 'MutableRefObject<unknown>' is not assignable to type 'LegacyRef<HTMLDivElement>'.
    Type 'MutableRefObject<unknown>' is not assignable to type 'RefObject<HTMLDivElement>'.
      Types of property 'current' are incompatible.
        Type '{}' is missing the following properties from type 'HTMLDivElement': align, addEventListener, removeEventListener, accessKey, and 235 more.
The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'

Компонент страницы

  const domNodeRef = useRef(null);
  const [search, setSearch] = useState("");

  useEffect(() => {
    const handler = (e) => {
      if (domNodeRef !== undefined || domNodeRef !== null) {
        if (!domNodeRef.current.contains(e.target)) {
          setSearch("");
        }
      }
    };
    document.addEventListener("mousedown", handler);

    return () => {
      document.addEventListener("mousedown", handler);
    };
  });

  return (
   <div className = "header">
     <div className = "header-content">
       <div className = "searchh">
         <input 
           placeholder = "Type to search"
           onChange = {handleSearchChange}
         />
         {!!search && (
           <SearchDropDown 
             search = {search}
             ref = {domNodeRef}
           />
         )}
       </div>
     </div>
   </div>
  )

Компонент SearchDropDown

const SearchDropDown = (props) => {
  ....
  return (
    <div className = "search-drop-down" ref = {props.ref}>
     .....
    </div>
  )
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
15
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

useRef вернет последовательный объект. Это никогда не будет null или undefined.

Что изменится, так это свойство .current в ссылке - это то, что вы должны проверить, а не сам объект ссылки.

if (domNodeRef !== undefined || domNodeRef !== null) {

следует изменить на

if (domNodeRef.current) {

Также

return () => {
  document.addEventListener("mousedown", handler);
};

должно быть

return () => {
  document.removeEventListener("mousedown", handler);
};

Однако вы можете рассмотреть другой подход - вместо ref и .contains просто проверьте, есть ли у цели элемент .closest в строке поиска:

useEffect(() => {
    const handler = (e) => {
        if (!e.target.closest('.search-drop-down')) {
            setSearch("");
        }
    }
    document.addEventListener("mousedown", handler);
    return () => {
        document.removeEventListener("mousedown", handler);
    };
}, []);

Другие вопросы по теме