Qiita初投稿です。最近ReactでGoogle Maps APIを扱うことが多いので自分用のTipsにする目的も兼ねて投稿してみました。
#最初の手順
-
$ create-react-app 'プロジェクト名'
で雛形を作成 -
npm i --save react-modal
コマンドでModalをコンポーネントとして扱えるようパッケージをinstall - ここからMaps用APIキー取得
- public/index.html 内に
<script>
タグでAPIキーを埋め込み- 例:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=取得したAPIキー"></script>
- 例:
#コンポーネントの構造
以下の通り。
- App (親コンポーネント)
- Modal (子コンポーネント)
- Map (孫コンポーネント)
- Modal (子コンポーネント)
#ソースコード
###親コンポーネント(App) + 子コンポーネント(Modal)
import React, { Component } from 'react'
import './App.css'
import ReactDOM from 'react-dom'
import Modal from 'react-modal'
export default class App extends Component {
constructor (props) {
super(props)
this.state = {
showModal: false,
}
this.openModal = this.openModal.bind(this)
this.closeModal = this.closeModal.bind(this)
}
openModal(){
this.setState({showModal: true})
}
closeModal(){
this.setState({showModal: false})
}
render(){
const custom = {
overlay : {
background: 'rgba(0,0,0, .4)'
},
content : {
top : '50%',
left : '50%',
right : 'auto',
bottom : 'auto',
marginRight : '-50%',
transform : 'translate(-50%, -50%)',
width : '72%',
height : '80%'
}
}
return (
<div className="AppComponent">
<input type="submit" className="button--submit" onClick={this.openModal} value="Open Map"/>
<Modal isOpen={this.state.showModal} shouldCloseOnOverlayClick={true}
onRequestClose={this.closeModal} style={custom} >
<Map />
</Modal>
</div>
)
}
}
Modalコンポーネントはreact-modalからインポートしてそのまま使うので、スタイルなどもまとめて親コンポーネントのクラス内に記述。isOpen
がTrueになった時にModalが表示されます。
今回は親コンポーネント上にボタンを置いて、それがクリックされることによってshowModalの状態をトグルして表示させています。
shouldCloseOnOverlayClick
がTrueならオーバーレイ部分をクリックするとModalが閉じる。
style
でModalのスタイルを直接render()内に記述することで指定できるのですが、他に良い方法がありそう・・・
###孫コンポーネント(Map)
export class Map extends Component{
constructor(props){
super(props)
this.state=({
map: null,
})
}
componentDidMount () {
const map = new window.google.maps.Map(
ReactDOM.findDOMNode(this.refs["map"]),
// document.getElementById('modalMap'),
{
center: new window.google.maps.LatLng(35.466642, 139.622485), //横浜駅
zoom: 17,
mapTypeId: 'roadmap'
}
);
this.setState({"map":map})
console.log('map is open')
}
render(){
return(
<div className="modal--map">
{/*<div ref="modalMap" className="modalMap"></div>*/} //document.getElementByIdを使う場合
<div ref="map" id="modalMap"/>
</div>
)
}
}
<div className="modal--map">
がrenderされてDOMツリーに追加された後にMapオブジェクトをcomponentDidMount()
で呼び出す仕組み。render内にmapのプロパティをベタ書きすると多分エラーになります、たしか。今回はReactDOM.findDOMNode
でref属性を持ったdivにMapを描画していますが、document.getElementById
を使う書き方も可能です。
#まとめ
Mapをコンポーネントとして実装するならreact-google-mapsを素直に使うほうが間違いなく近道ではあるのですが、単にちょっと表示させたいなら上記の方法で済ますこともいいのではないでしょうか。
ここから、Map上のマーカーをさらに子コンポーネントとして追加したり、Modalの中にMapと並列となるコンポーネントを追加して何かウェブアプリを構築していくのもいいかなーと考えています。
#参考リンク
[Reactでcontextを利用してGoogleMapAPIを叩く(Map,Marker)]
(https://qiita.com/sh4869/items/fcbcc6dee76d42572566)
[Google Maps JavaScript API 概要]
(https://developers.google.com/maps/documentation/javascript/?hl=ja)
[react-modal]
(https://github.com/reactjs/react-modal)