同じ問題に悩まされました。私はここのパーティーに少し遅れますが、私にとってこれは本当に良い解決策です。うまくいけば、それは他の誰かの助けになるでしょう。あなたは、インポートする必要があるfindDOMNode
からreact-dom
import ReactDOM from 'react-dom';
// ... ✂
componentDidMount() {
document.addEventListener('click', this.handleClickOutside, true);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClickOutside, true);
}
handleClickOutside = event => {
const domNode = ReactDOM.findDOMNode(this);
if (!domNode || !domNode.contains(event.target)) {
this.setState({
visible: false
});
}
}
React Hooksアプローチ(16.8 +)
という再利用可能なフックを作成できますuseComponentVisible
。
import { useState, useEffect, useRef } from 'react';
export default function useComponentVisible(initialIsVisible) {
const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
const ref = useRef(null);
const handleClickOutside = (event) => {
if (ref.current && !ref.current.contains(event.target)) {
setIsComponentVisible(false);
}
};
useEffect(() => {
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('click', handleClickOutside, true);
};
});
return { ref, isComponentVisible, setIsComponentVisible };
}
次に、コンポーネントに次の機能を追加します。
const DropDown = () => {
const { ref, isComponentVisible } = useComponentVisible(true);
return (
<div ref={ref}>
{isComponentVisible && (<p>Dropdown Component</p>)}
</div>
);
}
ここでコードサンドボックスの例を見つけてください。