はじめに
React-Leafletを試してみます。
最初にリポジトリからソースをダウンロードし、サンプルを動かして大まかを捉えます。
その後、ゼロから作成します。
公式サイト
React-Leaflet · ⚛️ React components for 🍃 Leaflet maps
Installation · React-Leaflet
v2.0 変更点
v2.0では、React v16.3で導入された新しいContext APIを活用するようです。
サンプル
サンプルの実行結果
以下で実行結果を見ることができます
React-Leaflet v2.0 test
作成
ゼロから実行します。
npm 等の環境構築は終わっているものとします。
今回のソースは以下に置いてます。
react-leaflet-v2-test/react-leaflet-v2-test at master · sugasaki/react-leaflet-v2-test
create-react-app
create-react-appでreactの雛形プロジェクトを作成します。
create-react-app react-leaflet-v2-test
インストール
インストール
npm install leaflet react-leaflet@next --save
Examples
Examplesにしたがってやっていきます。
今回は以下の2つをやります。
- A simple Marker with Popup
- Event handling
A simple Marker with Popup
マーカーを1個表示するだけのシンプルな地図コンポーネントを作成します。
simpleコンポーネント
src/components/simple.js を追加
import React, { Component } from 'react'
import { Map, TileLayer, Marker, Popup } from 'react-leaflet'
export default class SimpleExample extends Component {
state = {
lat: 51.505,
lng: -0.09,
zoom: 13,
}
render() {
const position = [this.state.lat, this.state.lng]
return (
<Map center={position} zoom={this.state.zoom}>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</Map>
)
}
}
App.js
App.jsを以下のように変更します。
import Leaflet from 'leaflet'
import React, { Component } from 'react';
import './App.css';
import 'leaflet/dist/leaflet.css';
import SimpleExample from './components/simple'
Leaflet.Icon.Default.imagePath =
'//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/images/'
class App extends Component {
render() {
return (
<SimpleExample />
);
}
}
export default App;
index.css
index.cssを修正
html, body {
margin: 10px;
padding: 0;
height: 100%;
width: 100%;
}
#root {
width: inherit;
height: inherit;
}
.leaflet-container {
width: 600px;
height: 300px;
margin: 10px;
}
結果
Event handling
クリックを検知してイベント発火、イベントでは現在地の取得を行います。
eventsコンポーネント
src/components/events.js を追加
import React, { createRef, Component } from 'react'
import { Map, TileLayer, Marker, Popup } from 'react-leaflet'
export default class EventsExample extends Component {
state = {
hasLocation: false,
latlng: {
lat: 51.505,
lng: -0.09,
},
}
mapRef = createRef()
handleClick = () => {
this.mapRef.current.leafletElement.locate()
}
handleLocationFound = e => {
this.setState({
hasLocation: true,
latlng: e.latlng,
})
}
render() {
const marker = this.state.hasLocation ? (
<Marker position={this.state.latlng}>
<Popup>
<span>You are here</span>
</Popup>
</Marker>
) : null
return (
<Map
center={this.state.latlng}
length={4}
onClick={this.handleClick}
onLocationfound={this.handleLocationFound}
ref={this.mapRef}
zoom={13}>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{marker}
</Map>
)
}
}
App.js
eventsの参照を追加します。
import EventsExample from './components/events'
また、renderに<EventsExample />
を追加します。
App.jsを以下のように変更します。
import Leaflet from 'leaflet'
import React, { Component } from 'react';
import './App.css';
import 'leaflet/dist/leaflet.css';
import SimpleExample from './components/simple'
import EventsExample from './components/events'
Leaflet.Icon.Default.imagePath =
'//cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/images/'
class App extends Component {
render() {
return (
<div>
SimpleExample
<SimpleExample />
EventsExample
<EventsExample />
</div>
);
}
}
export default App;