Невозможно переключить компонент во второй раз с помощью прослушивателей событий
Вы можете найти коды здесь .
У меня есть компонент, который выполняет следующие функции:
- Показать значок
- Если щелкнуть значок, то вместо него отобразится поле поиска.
- Если пользователь щелкает где-нибудь за пределами поля поиска, пока он отображается, скройте поле поиска и вместо этого снова покажите значок.
Проблема в том, что после того, как вы щелкнете по значку, поле поиска будет отображаться, а щелчок в любом месте за пределами поля поиска снова отобразит значок. Но если вы щелкните значок еще раз во второй раз, поисковый запрос не отобразится.
Я попытался прикрепить ссылку к значку и оценить, содержится ли событие при щелчке по значку, но этот условный оператор не помог. Как я могу убедиться, что, когда я нажимаю на значок еще несколько раз, ввод снова появляется? Спасибо!
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]);