今回はReactでコンポーネントの外側がクリックされたかどうかを判定する方法を解説します。モーダルの外側をクリックした時にモーダルを閉じるといった処理などに使えます。
サンプルとして四角形の内側がクリックされたら「内側」、外側がクリックされたら「外側」とコンソールに表示してみます。
デモはこちら↓(なぜか内側クリックは2回動作してますが原因は分からず…気合いで乗り切ろうね)
コンポーネントの外側がクリックされたかを判定する方法
コードは以下の通り(スタイルは省略しています)。
<div className="square">
がピンクの四角形です。
export default class App extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
// クリックされた要素が.squareの内側かどうか?
if (e.target.closest('.square')) {
console.log('内側');
} else {
console.log('外側')
}
}
componentDidMount() {
document.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClick)
}
render() {
return <div className="square" onClick={this.handleClick}></div>;
}
}
if文が要素の内側か外側かどうかを判定している箇所です。
e.target.closest('.square')
は、クリックした要素(=e.target
)の親要素が.squareかどうか(=.closest('.square')
)を判定し、trueなら内側、falseなら外側と判定します。
closest()
は親要素をセレクタで取得するメソッドですが、クリックされた要素自体も取得できます。使い方はjQueryのclosest()
と同じですね。
下のcomponentDidMount()
ですが、document.addEventListener()
が必要な理由は、コンポーネント内でonClick
イベントを発動しているのでこれを入れないとコンポーネントの外側をクリックした時に判定ができないからです。外側のイベントを検出するには全ての要素をイベントの対象にする必要があるということですね。
また、componentWillUnmount()
でアンマウント時にイベントを解除しておきます。
まとめ
Reactでコンポーネントの外側がクリックされたかどうかを判定する方法でした。
条件を増やせば、「こことここをクリックした時は内側の判定」みたいな感じにすることもできます。
モーダルなんかに使うといいのではないでしょうか。