Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8664

Escキー押下で閉じるモーダルウィンドウをReactで実装する

$
0
0

Reactで以下のようなモーダルウィンドウを実装してみました。
マークアップ構造と要件はこちらになります。
・モーダルのコンポーネント配下に、オーバーレイとダイアログが兄弟要素でこの順に続く
・オーバーレイをクリックで閉じる
・ESC押下で閉じる
・閉じるボタン押下で閉じる

また、ライブラリは使いません。
スタイリングはモーダルとしてのロジックのみである最低限のもので、デザインは未実装です。

ソースコード

App.jsx
classModalextendsReact.Component{constructor(props){super(props);this.handleKeyDown=this.handleKeyDown.bind(this);}componentDidMount(){document.addEventListener("keydown",this.handleKeyDown);}handleKeyDown(e){constescKey=e.keyCode===27;if(escKey){this.props.onKeyDown(e);}}render(){return(this.props.isOpen&&(<><divclassName="overlay"onClick={this.props.onOverlayClick}></div><divclassName="dialog"><buttononClick={this.props.onCloseClick}>Close</button>{this.props.children}</div></>));}}classAppextendsReact.Component{constructor(props){super(props);this.state={isOpen:false};this.handleOpenClick=this.handleOpenClick.bind(this);this.handleCloseClick=this.handleCloseClick.bind(this);this.handleOverlayClick=this.handleOverlayClick.bind(this);this.handleKeyDown=this.handleKeyDown.bind(this);}handleOpenClick(){this.setState({isOpen:true});}handleCloseClick(){this.setState({isOpen:false});}handleOverlayClick(){this.setState({isOpen:false});}handleKeyDown(){this.setState({isOpen:false});}render(){return(<div><buttononClick={this.handleOpenClick}>Open</button><ModalisOpen={this.state.isOpen}onCloseClick={this.handleCloseClick}onOverlayClick={this.handleOverlayClick}onKeyDown={this.handleKeyDown}><h2>How to close:</h2><ul><li>Press Esc key</li><li>Click Overlay</li><li>Click Close button</li></ul></Modal></div>);}}ReactDOM.render(<App/>,document.getElementById("root"));
App.scss
@mixinfullSize(){top:0;left:0;width:100%;height:100vh;}@mixinsetCenter(){top:50%;left:50%;transform:translate(-50%,-50%);}.overlay{position:fixed;@includefullSize();background-color:rgba(0,0,0,0.6);}.dialog{position:fixed;@includesetCenter();background-color:#fff;}

最低限のコードで、読んだほうが早い気がするので解説は省略します。

ちょっとハマった点

Escキー押下を実装するにあたり、
どこからでもキーボード押下を受け付けるにはどうするか?と悩みました。

hoge.js
// 例えばjQueryだと...$('body').on('keydown',function(){// ここに処理})

少しググってみたら解決しました。
キーボード押下を発火させたいコンポーネントのcomponentDidMountメソッド内に、
document.addEventListener("keydown", ここに処理) のように書きます。

Hoge.jsx
classHogeextendsReact.Component{constructor(props){super(props);this.handleKeyDown=this.handleKeyDown.bind(this);}componentDidMount(){document.addEventListener('keydown',this.handleKeyDown);}handleKeyDown(e){// ここに処理}// 以下略...

すなわちこのようになります。
あとは親コンポーネントにキーボード押下処理(this.setState{isOpen: false})を実装し、
Modalコンポーネントにpropsを生やしてから上記の押下処理を代入してあげます。
これで一息ついて完成しました。

実際に動くリンクはこちらになります。
https://codepen.io/yh424/pen/vYOJOxm

参考にしたサイト

キーボード押下処理:https://reactjsexample.com/close-react-component-by-pressing-escape-or-clicking-outside-of-it/
モーダル実装:https://codepen.io/alligatorio/pen/aYzMKL

※ソースコードは参考にさせて頂きましたが、最終的な概形はこれらのリンクとは大きく違っています

備考

オーバーレイとダイアログもコンポーネント化すると使い回しが利きやすくなるかもしれません。


Viewing all articles
Browse latest Browse all 8664

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>