Невозможно переключить компонент во второй раз с помощью прослушивателей событий

Вы можете найти коды здесь .

У меня есть компонент, который выполняет следующие функции:

  1. Показать значок
  2. Если щелкнуть значок, то вместо него отобразится поле поиска.
  3. Если пользователь щелкает где-нибудь за пределами поля поиска, пока он отображается, скройте поле поиска и вместо этого снова покажите значок.

Проблема в том, что после того, как вы щелкнете по значку, поле поиска будет отображаться, а щелчок в любом месте за пределами поля поиска снова отобразит значок. Но если вы щелкните значок еще раз во второй раз, поисковый запрос не отобразится.

Я попытался прикрепить ссылку к значку и оценить, содержится ли событие при щелчке по значку, но этот условный оператор не помог. Как я могу убедиться, что, когда я нажимаю на значок еще несколько раз, ввод снова появляется? Спасибо!

      import ReactDOM from "react-dom";
import "@elastic/eui/dist/eui_theme_amsterdam_light.css";
import React, { useEffect, useRef, useState } from "react";
import { EuiButtonIcon, EuiFieldText } from "@elastic/eui";

const App = () => {
  const [showSearch, setShowSearch] = useState(false);
  const searchInputRef = useRef(null);

  useEffect(() => {
    document.addEventListener(
      "click",
      (event) => handleClickOutside(event, showSearch),
      false
    );
  }, [showSearch]);

  useEffect(
    () => () => {
      document.removeEventListener(
        "click",
        (event) => handleClickOutside(event, false),
        false
      );
    },
    []
  );

  const handleClickOutside = (event, showSearch) => {
    if (
      searchInputRef.current &&
      !searchInputRef.current.contains(event.target) &&
      showSearch
    ) {
      setShowSearch(false);
    }
  };

  if (showSearch) {
    return (
      <EuiFieldText
        icon="search"
        placeholder="Sample Search Placeholder ..."
        inputRef={searchInputRef}
      />
    );
  }

  return (
    <EuiButtonIcon
      aria-label="button"
      iconType="search"
      iconSize="xxl"
      onClick={() => setShowSearch(true)}
    />
  );
};

export default App;

1 ответ

Решение

Думаю, ваш подход был правильным, я изменил только функции.

Я просто удалил другой useEffect функция, которую вы использовали для удаления click мероприятие.

Я также прошел once для прослушивателя событий, поэтому событие будет удалено после однократного запуска.

      useEffect(() => {
  const handleClickOutside = () => document.addEventListener("click", ({ target }) => {
    if (searchInputRef.current?.contains(target) === false && showSearch === true) setShowSearch(false);
    else handleClickOutside();
  }, { once: true });

  handleClickOutside();
}, [showSearch]);

Редактировать dazziling-code

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