Почему ref не может получить доступ к своему дочернему элементу?

Добрый день! <br/> <br/> Можете подсказать, в чем заключается проблема? <br/> <br/> У меня есть контейнер: <br/> <pre><code>&lt;div className={cls["CustomSelect-listWrap"]} ref={ref}&gt;
.//Тут селект
&lt;div&gt;Селект&lt;/div&gt;
&lt;/div&gt;</code></pre> <br/> <br/> Я сортирую селекты перед выводом в контейнер следующим образом: <br/> <pre><code>const itemsSort = search
    ? items.filter((item) =&gt;
        item.name.toLowerCase().includes(search.toLowerCase())
      )
    : selectedValue
    ? selectedValue.length &gt; 0
      ? items.filter((item) =&gt; {
          const newItem = !selectedValue.includes(item);

          return newItem == true ? item : null;
        })
      : items
    : items;</code></pre> <br/> <br/> Далее у меня есть useEffect, в котором я отслеживаю клики вне компонента, и при их обнаружении закрываю селект: <br/> <pre><code>useEffect(() =&gt; {
    // Закрываем селект при нажатии вне селекта
    console.log('render')
    if (!showList) return;

    const handleClick = (e) =&gt; {
      console.log(e.target);
      if (refPanel.current.contains(e.target)) {
        return console.log("isPanel");
      }
      if (!ref.current.contains(e.target)) {
        console.log(e.target, "aget");
        return setShowList(false);
      }
    };

    document.addEventListener("click", handleClick);
    return () =&gt; document.removeEventListener("click", handleClick);
  }, [showList]);</code></pre> <br/> <br/> Однако при клике на селект контейнер закрывается. Если же рассчитать по следующему принципу, то контейнер не закрывается: <br/> <pre><code>const itemsSort = search
    ? items.filter((item) =&gt;
        item.name.toLowerCase().includes(search.toLowerCase())
      )
    : it
  • 31 октября 2024 г. 7:03
Ответы на вопрос 1
Добрый день!

Давайте разберемся в вашей проблеме. Вы говорите, что при клике на селект контейнер закрывается, хотя это не должно происходить. Это может происходить из-за неправильной работы с `ref` или слишком строгих проверок в вашем обработчике событий.

1. **Проверка `ref`:** Убедитесь, что `ref` действительно ссылается на нужный DOM-элемент. Если `ref` ссылается на другой элемент или не устанавливается должным образом, метод `contains` не будет работать как ожидается. Убедитесь, что вы используете `ref` в правильно созданном элементе:

    ```jsx
    const ref = useRef(null); // создаем реф

    return (
      <div className={cls["CustomSelect-listWrap"]} ref={ref}>
        <div>Селект</div>
        ...
      </div>
    );
    ```

2. **Проверка `handleClick`:** Проверьте, правильно ли вы используете `contains` метод для `ref`. Убедитесь, что `ref.current` не равен `null`:

    ```jsx
    const handleClick = (e) => {
      console.log(e.target);
      if (ref.current && ref.current.contains(e.target)) {
        return console.log("isPanel");
      }
      // Проверка нажатия вне контейнера
      if (ref.current && !ref.current.contains(e.target)) {
        console.log(e.target, "aget");
        return setShowList(false);
      }
    };
    ```

3. **Проверка инициализации `ref`:** Если `ref` не инициализирован, например, из-за несовпадения компонентов или потери ссылки, это может вызвать проблемы. Убедитесь, что проверка `ref.current` выполняется на каждом этапе вашей логики.

4. **Структура компонента:** Иногда могут возникать проблемы из-за структуры компонентов или неправильного рендеринга. Убедитесь, что ваши селекты, и их контейнеры корректно вложены в сам компонент и корректно подаются в `render`.

5. **Логгирование:** Добавьте дополнительные `console.log`, чтобы понять, какой именно элемент получает событие клика и каковы значения `ref.current`. Это может помочь найти, почему проверка не срабатывает.

Следуя этим шагам, вы сможете лучше понять проблему и устранить её. Если проблема сохраняется, попробуйте предоставить более полный контекст кода или ошибку, чтобы дальнейший анализ был целесообразнее.
Похожие вопросы