LoginSignup
0
1

More than 1 year has passed since last update.

ReactでGoogleMapsAPIを使う(#3地図にカスタムコントロールを表示)

Last updated at Posted at 2021-11-12

前回記事に引き続き、ReactでGoogleMapsAPIを触っていきます。
今回はカスタムコントロールを追加してみます。
地図の上部にInputボックスを入れるこんなやつを作ります。
2021-11-12 22.28.06.png

前回作ったコンポーネントの確認

こんな感じでTest.jsとMap.jsを作ってました。
前回記事でMarkerコンポーネントを作っていますが、今回はここは無関係。

Test.js
import { Wrapper} from "@googlemaps/react-wrapper";
import Map from "./Map";
import Marker from "./Marker";

export default function Test(){

const positions =[
  {
          lat: 35.6809591,
          lng: 139.7673068,
      },
      {
          lat: 35.675069,
          lng: 139.763328,
      }
  ]

return (

<Wrapper apiKey={"ここにAPIkey"} >
  <MyMap>
  {positions.map(p=><Marker position={p}/>)}
  </MyMap>
</Wrapper>
)
}

Map.js
import React,{useRef,useEffect,useState} from 'react';

export default function Map({children}){
  const ref = useRef(null);
  const [map, setMap] = useState();

 useEffect(() => {
  if (ref.current && !map) {
    setMap(new window.google.maps.Map(ref.current, {
       center:{
          lat: 35.6809591,
          lng: 139.7673068,
      },
      zoom:14,
      mapTypeControl: false,
      streetViewControl: false,
      fullscreenControl: false,
    }));

  }
}, [ref, map]);

return(  <>
    <div ref={ref} style={{height:500, width:500}} />
    {React.Children.map(children, (child) => {
      if (React.isValidElement(child)) {
        return React.cloneElement(child, { map });
      }
    })}
  </>
  )
}

SearchBoxコンポーネントを作る。

地図内の上部に表示する検索窓を作るため、コンポーネントを作ります。

SearchBox.js
import React,{useRef,useEffect,useState} from 'react';

export default function SearchBox(props){
  const searchRef = useRef(null);

 useEffect(() => {
  if (props.map) {
      props.map.controls[google.maps.ControlPosition.TOP_CENTER].push(searchRef.current);
  }},[props.map])

return( 
     <input
      type="text"
      placeholder="ここに入力してください!"
      ref={searchRef}
      style={{
       border : "2px solid #fff",
       borderRadius : "3px",
       boxShadow : "0 2px 6px rgba(0,0,0,.3)",
       marginTop : "8px",
       textAlign:"center",
       width:400,
       height:40,
      }}
    />
  )
}

2点ほどポイントを説明すると、

親コンポーネント(Test.js)から子コンポーネント(Search.js)にmapインスタンスを渡す

前回記事でMarkerを追加した際にTest.jsは以下のように子コンポーネントにmapインスタンスを渡せるようにしました。

Test.js
return(  <>
    <div ref={ref} style={{height:500, width:500}} />
    {React.Children.map(children, (child) => {
      if (React.isValidElement(child)) {
        return React.cloneElement(child, { map });
      }
    })}
  </>
  )

上記により子コンポーネント(SearchBox)では受け取ったmapが使える。

SearchBoxコンポーネント内、useEffectを用いて以下を記載することで、地図内上部中央にカスタムコントロールを表示できます。

SearchBox.js
 useEffect(() => {
  if (props.map) {
props.map.controls[google.maps.ControlPosition.TOP_CENTER].push(searchRef.current);
  }},[props.map])

親コンポーネントを書き換える。

SearchBoxを作ったので親コンポーネントである(Test.js)に追加します。

import { Wrapper} from "@googlemaps/react-wrapper";
import Map from "./Map";
import Marker from "./Marker";
import SearchBox from "./SearchBox";

export default function Test(){

const positions =[
  {
          lat: 35.6809591,
          lng: 139.7673068,
      },
      {
          lat: 35.675069,
          lng: 139.763328,
      }
  ]

return (
 <Wrapper apiKey={"ここにAPIキー"} >
   <Map>
   {positions.map((p,index)=><Marker position={p} key={index}/>)}
   <SearchBox/>
   </Map>
 </Wrapper>
)
}

完成!

2021-11-12 22.28.06.png

0
1
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
0
1