LoginSignup
55
48

More than 3 years have passed since last update.

ReactでGoogle mapをお届けする

Posted at

はじめに

ReactでMapを使用し以下要件を満たす必要があった

・ マップスタイルの変更
・ ピンスタイルの変更
・ ピン間に線を描画する
・ ピンをクリックすると吹き出しが表示される

要件を満たすためにReactで使用可能なMapをレンダリングできるライブラリをざっと調査した

ライブラリ

ライブラリ ピン変更 バルーン機能 ルーティング 備考
google-maps-react Markerコンポーネントを提供している infoWindowで変更可能 polylineで設定可能 weekly download 24,085
google-map-react 子コンポ-ネント内に画像やスタイルを適用したコンポーネントで対応 子コンポーネントで吹き出しコンポーネントを配置しonChildClickで表示する onGoogleApiLoaded時に描画可能 weekly download 69,369
react-google-maps componentのcoordinates内で変更可能 infoWindowをカスタム onLoaded時に描画可能 ・weekly download 2,414
UI componentを豊富に提供
2gis-maps-react 細かいアイコンの設定が可能 popuupで設定可能 polylineで線を引ける ・no longer supported
・weekly download 15
react-map-gl markerで設定可能 popuupで設定可能 overlay機能を仕様しcanvasに線を引ける ・mapboxを使用可能
・weekly download 34,397

今回は単純にコミュニティがアクティブかどうか、公式サンプルが豊富かという視点でgoogle-map-reactを使用することにした

また、マップスタイルの変更としてsnazzymapsが豊富なサンプルを提供しているので今回使用することにした

実装

google-map-reactでピンを一個だけマップ上に表示したい場合はとても簡単に実装できる

import * as React from 'react'
import styled from 'styled-components'
import logo from './logo.svg'
import GoogleMapReact from 'google-map-react'

const App = () => (
  <Wrapper>
    <Header>
      <Logo src={logo} />
      <H1>Welcome to React</H1>
    </Header>
    <GoogleMapWrapper>
    <GoogleMapReact
      bootstrapURLKeys={{
        key: {'ここにgoogle map apiのkeyをドウゾ'}
      }}
      defaultCenter={{
        lat: 43.0582954,
        lng: 141.3466919
      }}
      defaultZoom={15}
    >
      <Pin
        lat={43.0582954}
        lng={141.3466919}
      >
      おおおんどおり
      </Pin>
    </GoogleMapReact>
    </GoogleMapWrapper>
  </Wrapper>
)

const Wrapper = styled.div`
  text-align: center;
`
const Header = styled.header`
  background-color: ${Color.Primary};
  height: 150px;
  padding: 20px;
  color: white;
`
const Logo = styled.img`
  animation: App-logo-spin infinite 20s linear;
  height: 80px;
  @keyframes App-logo-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
`
const H1 = styled.h1`
  font-size: 1.5em;
`
const Pin = styled.div<{
  lat: number,
  lng: number
}>`
`

const GoogleMapWrapper = styled.div`
  height: 100vh;
  width: 100%;
`

export default App

これを適用すると大通公園に"おおおんどおり"と表示されてるはずだ
サンプルを参考にするだけでとても簡単にピンを配置できる

マップスタイル変更

Googleマップのデザインを以下のように変更したいケースがあると思う


実はsnazzymapというサイトを使えば簡単に実装できる

import * as React from 'react'
import styled from 'styled-components'
import { Color } from './brand'
import logo from './logo.svg'
import GoogleMapReact, { MapOptions, Maps } from 'google-map-react'

const App = () => {
  const createMapOptions = (maps: Maps): MapOptions => {
    return {
      mapTypeControlOptions: {
        position: maps.ControlPosition.TOP_RIGHT,
      },
      mapTypeControl: false,
      zoomControl: false,
      scaleControl: false,
      streetViewControl: false,
      fullscreenControl: false,
      styles: [
        {
          featureType: 'water',
          elementType: 'geometry',
          stylers: [
            {
              color: '#e9e9e9',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'landscape',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 29,
            },
            {
              weight: 0.2,
            },
          ],
        },
        {
          featureType: 'road.arterial',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 18,
            },
          ],
        },
        {
          featureType: 'road.local',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          featureType: 'poi',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          featureType: 'poi.park',
          elementType: 'geometry',
          stylers: [
            {
              color: '#dedede',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          elementType: 'labels.text.stroke',
          stylers: [
            {
              visibility: 'on',
            },
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          elementType: 'labels.text.fill',
          stylers: [
            {
              saturation: 36,
            },
            {
              color: '#333333',
            },
            {
              lightness: 40,
            },
          ],
        },
        {
          elementType: 'labels.icon',
          stylers: [
            {
              visibility: 'off',
            },
          ],
        },
        {
          featureType: 'transit',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f2f2f2',
            },
            {
              lightness: 19,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 17,
            },
            {
              weight: 1.2,
            },
          ],
        },
      ],
    }
  }
  return (
    <Wrapper>
      <Header>
        <Logo src={logo} />
        <H1>Welcome to React</H1>
      </Header>
      <GoogleMapWrapper>
      <GoogleMapReact
        bootstrapURLKeys={{
          key: ''
        }}
        defaultCenter={{
          lat: 43.0582954,
          lng: 141.3466919
        }}
        defaultZoom={15}
        options={createMapOptions}
      >
        <Pin
          lat={43.0582954}
          lng={141.3466919}
        >
        おおおんどおり
        </Pin>
      </GoogleMapReact>
      </GoogleMapWrapper>
    </Wrapper>
  )
}

const Wrapper = styled.div`
  text-align: center;
`
const Header = styled.header`
  background-color: ${Color.Primary};
  height: 150px;
  padding: 20px;
  color: white;
`
const Logo = styled.img`
  animation: App-logo-spin infinite 20s linear;
  height: 80px;
  @keyframes App-logo-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
`
const H1 = styled.h1`
  font-size: 1.5em;
`
const Pin = styled.div<{
  lat: number,
  lng: number
}>`
`

const GoogleMapWrapper = styled.div`
  height: 100vh;
  width: 100%;
`

export default App

createMapOptionsのfullscreenControl optionの下にstyles optionがある
このstyles optionにsnazzymapで取得したソースコードをコピペするだけで実装できる

ちなみに今回はSubtle Grayscaleを適用した

ピンスタイルの変更

前述通りピンを1個だけ描画したい場合はとても簡単にできるが複数ピンのスタイルを変更し描画したい場合はどうすればいいのかともしかしたらなるかもしれない
これも簡単に実装できる

複数ピンの描画位置に関しては、GoogleMapReactの1階層子コンポーネントでlatやlngを元に相対位置をよしなに算出してくれるので子コンポーネントにスタイルを適用するだけで実装ができる

import * as React from 'react'
import styled from 'styled-components'
import { Color } from './brand'
import logo from './logo.svg'
import GoogleMapReact, { MapOptions, Maps } from 'google-map-react'

const App = () => {
  const pins: {
    lat: number,
    lng: number,
    name: string
  }[] = [
    {
      lat: 43.0543412,
      lng: 141.355018,
      name: 'お姉さんレーベル'
    },
    {
      lat: 43.0543451,
      lng: 141.3528293,
      name: '姉キャバ ジャックローズ'
    }
  ]
  const createMapOptions = (maps: Maps): MapOptions => {
    return {
      mapTypeControlOptions: {
        position: maps.ControlPosition.TOP_RIGHT,
      },
      mapTypeControl: false,
      zoomControl: false,
      scaleControl: false,
      streetViewControl: false,
      fullscreenControl: false,
      styles: [
        {
          featureType: 'water',
          elementType: 'geometry',
          stylers: [
            {
              color: '#e9e9e9',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'landscape',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 29,
            },
            {
              weight: 0.2,
            },
          ],
        },
        {
          featureType: 'road.arterial',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 18,
            },
          ],
        },
        {
          featureType: 'road.local',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          featureType: 'poi',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          featureType: 'poi.park',
          elementType: 'geometry',
          stylers: [
            {
              color: '#dedede',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          elementType: 'labels.text.stroke',
          stylers: [
            {
              visibility: 'on',
            },
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          elementType: 'labels.text.fill',
          stylers: [
            {
              saturation: 36,
            },
            {
              color: '#333333',
            },
            {
              lightness: 40,
            },
          ],
        },
        {
          elementType: 'labels.icon',
          stylers: [
            {
              visibility: 'off',
            },
          ],
        },
        {
          featureType: 'transit',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f2f2f2',
            },
            {
              lightness: 19,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 17,
            },
            {
              weight: 1.2,
            },
          ],
        },
      ],
    }
  }
  return (
    <Wrapper>
      <Header>
        <Logo src={logo} />
        <H1>Welcome to React</H1>
      </Header>
      <GoogleMapWrapper>
      <GoogleMapReact
        bootstrapURLKeys={{
          key: ''
        }}
        defaultCenter={{
          lat: 43.0543451,
          lng: 141.3528293
        }}
        defaultZoom={15}
        options={createMapOptions}
      >
      {
        pins.map((pin: {
          lat: number,
          lng: number,
          name: string
        }) => (
          <Pin
            lat={pin.lat}
            lng={pin.lng}
          >
          {pin.name}
          </Pin>
        ))
      }
      </GoogleMapReact>
      </GoogleMapWrapper>
    </Wrapper>
  )
}

const Wrapper = styled.div`
  text-align: center;
`
const Header = styled.header`
  background-color: ${Color.Primary};
  height: 150px;
  padding: 20px;
  color: white;
`
const Logo = styled.img`
  animation: App-logo-spin infinite 20s linear;
  height: 80px;
  @keyframes App-logo-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
`
const H1 = styled.h1`
  font-size: 1.5em;
`
const Pin = styled.div<{
  lat: number,
  lng: number
}>`
`

const GoogleMapWrapper = styled.div`
  height: 100vh;
  width: 100%;
`

export default App

お姉さんレーベルと姉キャバ ジャックローズが表示されてることが確認できると思う
あとは、Pinコンポーネントのstyleを変更すればデザインは簡単に変更可能だ

ピン間に線を描画する

GoogleMapReactではGoogle map apiのloaded時に上乗せ描画できるapiを提供している
例えば線を描画するpolylineがある
今回はpolylineを使用しでピン間に線を引く

import * as React from 'react'
import styled from 'styled-components'
import { Color } from './brand'
import logo from './logo.svg'
import GoogleMapReact, { MapOptions, Maps } from 'google-map-react'
interface PinProps {
  lat: number,
  lng: number,
  name: string
}
const App = () => {
  const pins: PinProps[] = [
    {
      lat: 43.0543412,
      lng: 141.355018,
      name: 'お姉さんレーベル'
    },
    {
      lat: 43.0543451,
      lng: 141.3528293,
      name: '姉キャバ ジャックローズ'
    }
  ]
  const apiLoaded = (map: any, maps: any, pins: any) => {
    const path = new maps.Polyline({
      path: pins.map((p: PinProps) => ({
        lat: p.lat,
        lng: p.lng
      })),
      geodesic: true,
      strokeColor: '#356859',
      strokeOpacity: 1,
      strokeWeight: 3,
    })

    path.setMap(map)
  }
  const createMapOptions = (maps: Maps): MapOptions => {
    return {
      mapTypeControlOptions: {
        position: maps.ControlPosition.TOP_RIGHT,
      },
      mapTypeControl: false,
      zoomControl: false,
      scaleControl: false,
      streetViewControl: false,
      fullscreenControl: false,
      styles: [
        {
          featureType: 'water',
          elementType: 'geometry',
          stylers: [
            {
              color: '#e9e9e9',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'landscape',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 29,
            },
            {
              weight: 0.2,
            },
          ],
        },
        {
          featureType: 'road.arterial',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 18,
            },
          ],
        },
        {
          featureType: 'road.local',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          featureType: 'poi',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          featureType: 'poi.park',
          elementType: 'geometry',
          stylers: [
            {
              color: '#dedede',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          elementType: 'labels.text.stroke',
          stylers: [
            {
              visibility: 'on',
            },
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          elementType: 'labels.text.fill',
          stylers: [
            {
              saturation: 36,
            },
            {
              color: '#333333',
            },
            {
              lightness: 40,
            },
          ],
        },
        {
          elementType: 'labels.icon',
          stylers: [
            {
              visibility: 'off',
            },
          ],
        },
        {
          featureType: 'transit',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f2f2f2',
            },
            {
              lightness: 19,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 17,
            },
            {
              weight: 1.2,
            },
          ],
        },
      ],
    }
  }
  return (
    <Wrapper>
      <Header>
        <Logo src={logo} />
        <H1>Welcome to React</H1>
      </Header>
      <GoogleMapWrapper>
      <GoogleMapReact
        bootstrapURLKeys={{
          key: ''
        }}
        defaultCenter={{
          lat: 43.0543451,
          lng: 141.3528293
        }}
        defaultZoom={15}
        options={createMapOptions}
        onGoogleApiLoaded={({ map, maps }) => apiLoaded(map, maps, pins)}
      >
      {
        pins.map((pin: {
          lat: number,
          lng: number,
          name: string
        }) => (
          <Pin
            lat={pin.lat}
            lng={pin.lng}
          >
          {pin.name}
          </Pin>
        ))
      }
      </GoogleMapReact>
      </GoogleMapWrapper>
    </Wrapper>
  )
}

const Wrapper = styled.div`
  text-align: center;
`
const Header = styled.header`
  background-color: ${Color.Primary};
  height: 150px;
  padding: 20px;
  color: white;
`
const Logo = styled.img`
  animation: App-logo-spin infinite 20s linear;
  height: 80px;
  @keyframes App-logo-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
`
const H1 = styled.h1`
  font-size: 1.5em;
`
const Pin = styled.div<{
  lat: number,
  lng: number
}>`
`

const GoogleMapWrapper = styled.div`
  height: 100vh;
  width: 100%;
`

export default App

お姉さんレーベルと姉キャバ ジャックローズの間に緑色の線が引かれていることが確認できるだろう

ピンをクリックすると吹き出しが表示される

GoogleMapReactは子コンポーネントのクリック時にイベント取得するonChildClickというapiを提供している
onChildClickはイベント発生時に該当するコンポーネントのkeyと子コンポーネント自体の情報(childProps)を返す

基本吹き出しを表示する際はクリックイベントのkeyとmapのindexが同じなら表示するで実装できるので、基本childPropsは使用しなくていいだろう

import * as React from 'react'
import styled from 'styled-components'
import { useState } from 'react'
import { Color } from './brand'
import logo from './logo.svg'
import GoogleMapReact, { MapOptions, Maps } from 'google-map-react'
interface PinProps {
  lat: number,
  lng: number,
  name: string
}
const App = () => {
  const [currentKey, setCurrentKey] = useState(-1)
  const pins: PinProps[] = [
    {
      lat: 43.0543412,
      lng: 141.355018,
      name: 'お姉さんレーベル'
    },
    {
      lat: 43.0543451,
      lng: 141.3528293,
      name: '姉キャバ ジャックローズ'
    }
  ]
  const apiLoaded = (map: any, maps: any, pins: any) => {
    const path = new maps.Polyline({
      path: pins.map((p: PinProps) => ({
        lat: p.lat,
        lng: p.lng
      })),
      geodesic: true,
      strokeColor: '#356859',
      strokeOpacity: 1,
      strokeWeight: 3,
    })

    path.setMap(map)
  }
  const changeBalloon = (key: string) => {
    const keyNumber = Number(key)
    if (currentKey === keyNumber) {
      setCurrentKey(-1)
    } else {
      setCurrentKey(keyNumber)
    }
  }
  const createMapOptions = (maps: Maps): MapOptions => {
    return {
      mapTypeControlOptions: {
        position: maps.ControlPosition.TOP_RIGHT,
      },
      mapTypeControl: false,
      zoomControl: false,
      scaleControl: false,
      streetViewControl: false,
      fullscreenControl: false,
      styles: [
        {
          featureType: 'water',
          elementType: 'geometry',
          stylers: [
            {
              color: '#e9e9e9',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'landscape',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 17,
            },
          ],
        },
        {
          featureType: 'road.highway',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 29,
            },
            {
              weight: 0.2,
            },
          ],
        },
        {
          featureType: 'road.arterial',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 18,
            },
          ],
        },
        {
          featureType: 'road.local',
          elementType: 'geometry',
          stylers: [
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          featureType: 'poi',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f5f5f5',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          featureType: 'poi.park',
          elementType: 'geometry',
          stylers: [
            {
              color: '#dedede',
            },
            {
              lightness: 21,
            },
          ],
        },
        {
          elementType: 'labels.text.stroke',
          stylers: [
            {
              visibility: 'on',
            },
            {
              color: '#ffffff',
            },
            {
              lightness: 16,
            },
          ],
        },
        {
          elementType: 'labels.text.fill',
          stylers: [
            {
              saturation: 36,
            },
            {
              color: '#333333',
            },
            {
              lightness: 40,
            },
          ],
        },
        {
          elementType: 'labels.icon',
          stylers: [
            {
              visibility: 'off',
            },
          ],
        },
        {
          featureType: 'transit',
          elementType: 'geometry',
          stylers: [
            {
              color: '#f2f2f2',
            },
            {
              lightness: 19,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.fill',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 20,
            },
          ],
        },
        {
          featureType: 'administrative',
          elementType: 'geometry.stroke',
          stylers: [
            {
              color: '#fefefe',
            },
            {
              lightness: 17,
            },
            {
              weight: 1.2,
            },
          ],
        },
      ],
    }
  }
  return (
    <Wrapper>
      <Header>
        <Logo src={logo} />
        <H1>Welcome to React</H1>
      </Header>
      <GoogleMapWrapper>
        <GoogleMapReact
          bootstrapURLKeys={{
            key: ''
          }}
          defaultCenter={{
            lat: 43.0543451,
            lng: 141.3528293
          }}
          defaultZoom={15}
          options={createMapOptions}
          onGoogleApiLoaded={({ map, maps }) => apiLoaded(map, maps, pins)}
          onChildClick={(key: string) => changeBalloon(key)}
        >
        {
          pins.map((
            pin: {
              lat: number,
              lng: number,
              name: string
            },
            index: number) => (
            <Pin
              lat={pin.lat}
              lng={pin.lng}
            >
            {pin.name}
            {
              index === currentKey &&
              'こんにちは'
            }
            </Pin>
          ))
        }
        </GoogleMapReact>
      </GoogleMapWrapper>
    </Wrapper>
  )
}

const Wrapper = styled.div`
  text-align: center;
`
const Header = styled.header`
  background-color: ${Color.Primary};
  height: 150px;
  padding: 20px;
  color: white;
`
const Logo = styled.img`
  animation: App-logo-spin infinite 20s linear;
  height: 80px;
  @keyframes App-logo-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
  }
`
const H1 = styled.h1`
  font-size: 1.5em;
`
const Pin = styled.div<{
  lat: number,
  lng: number
}>`
`

const GoogleMapWrapper = styled.div`
  height: 100vh;
  width: 100%;
`

export default App

それぞれの子コンポーネントをクリックすると"こんにちは"が表示されるだろう
onGoogleApiLoadedのmapsからgoogle apiのdraw機能を扱うことができる
参照

useStateがよくわからねえという方は自分で勉強してください

まとめ

今回使用したライブラリの使用事例の記事がなかなか見つからなかったので、今回記事にし公開することにした
これからReactでgoogle mapの使用を検討している方に少しでも参考になれば幸いだ

今回作成したサンプルはこちら

55
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
48