#javascript #reactjs
#javascript #reactjs
Вопрос:
В главном файле приложения (App.js ) У меня есть этот код, <button>
здесь можно отключить компонент «Выпадающий список»
return (
<div>
<button
onClick={() => {
console.log("App button"); // First
setShowDropDown(!showDropDown);
}}
>
Toggle Dropdown
</button>
{showDropDown ? (
<Dropdown
selected={selected}
onSelectedChange={setSelected}
options={options}
/>
) : null}
</div>
);
В выпадающем файле компонента (Dropdown.js ) Это событие onBodyClick
делает выпадающее меню неактивным при нажатии на любое место, кроме самого выпадающего меню.
Цель здесь — отменить событие с помощью функции очистки useEffect
при нажатии на кнопку. Проблема в том, что когда я нажимаю кнопку, порядок того, что произошло, примерно такой :
- Сначала:
onClick
событие кнопки и «размонтирование». - Второе:
onBodyClick
событие. - Наконец: очистка. Этот порядок создает проблему, когда я нажимаю на кнопку, потому что событие происходит после размонтирования. Как я могу это решить? ошибка: не удается прочитать свойство ‘contains’ из null
useEffect(() => {
const onBodyClick = (event) => {
console.log("event"); // Second
if (ref.current.contains(event.target)) {
return;
}
setOpen(false);
};
document.body.addEventListener("click", onBodyClick);
return () => {
console.log("cleanup"); // Finally
document.body.removeEventListener("click", onBodyClick);
};
}, []);
Комментарии:
1. Не удается прочитать свойство ‘contains’ из null
Ответ №1:
Похоже, вам просто нужно сначала проверить, существует ли ссылка:
const onBodyClick = (event) => {
if (!ref.current) {
// Component is unmounting
// below line could be used or commented out; since the component is unmounting,
// the state should not make a difference
// setOpen(false);
return
}
if (ref.current.contains(event.target)) {
// Component is not unmounting, and click was inside ref
return;
}
// Component is not unmounting, and click was outside ref
setOpen(false);
};
Ответ №2:
У меня такая же проблема, и это работает для меня
if(this.wrapperRef amp;amp; !this.wrapperRef.contains(event.target) {
this.setState({visibility: false});
}
Я проверяю, существует ли wrapperRef, и я проверяю, содержит ли оболочка элемент Html
Я знаю, что вы используете перехватчики реакции, но идея та же.