3

您可以在此处找到代码和框。

我有一个执行以下操作的组件:

  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;
4

1 回答 1

4

我认为你的方法是正确的,我改变的只是useEffect功能。

我刚刚删除了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]);

编辑令人眼花缭乱的代码

于 2021-10-10T21:05:51.077 回答