React and Google Maps Api

前言

我知道現在在github上有現成的React Google Maps的套件,但是想透過這次的研究,了解google maps api是如何運作的,下次應該就直接用套件了吧XD

目標

在全屏的Google Maps地圖上,只要點擊地圖,取得地圖上的坐標,就能知道那個地點的天氣

熱身(Optional)

依照Google官網上的api文件[1],和Youtube上的教學影片[2],建立一個有基本版面的地圖

整合至React

依照這個網站[3]的文章,建立Component後,先在Render()建立一個想要放入地圖的Div,再來componentDidMount放入在上面寫的initMap function,並且在index.html加入Google Maps Api的Javascript,就能完成一個在React上的簡單地圖。

點擊增加Marker

目前的地圖是靜態提供Marker,根據Google Maps Api的文件[4],我改寫了當中的map.addListener,把上面提供new google.maps.Marker的方法加進去,這樣你的React地圖點擊就會有新的Marker了!

刪除舊有的Marker

根據文件[5],map.setMap(null)只能隱藏標記,也不能隱藏我點擊增加的Marker,參考了文件[6],在Component上面增加了兩個Global Variable:map和markers[],加上setMapOnAll、clearMarkers、deleteMarkers的function,就能完整的刪除標記了。

原理

利用增加Marker後,把Marker推到markers的陣列:markers.push(marker),再map.addListener中先刪除Marker,才再新增。

坐標與Open Weather Api整合

在原有的程式整合這個Component後,我在程式原有的State加上lat和lng來儲存從Google Maps Api從來的坐標,並且提供Component onClick={handleClick}的的Callback function,來接從Component收到map.addListener產生的坐標。這樣在收到坐標的改變後,顯示天氣的元件也會隨著改變。不過在串接天氣Api的過程中,有一個很奇怪的問題:

Axios api 無限loop

我一開始想說把抓到的坐標放到我的State,但卻一直無限loop,把this.setState的lat、lng拿掉之後,就沒事了,真的很怪異,不知道誰能幫我解答XD


    getLocationWeather(lat, lng, unit){
        this.setState = ({
            lat: lat,
            lng: lng
        }, () => {

        //結論:糾結了一整個下午,為什麼加了上面的setState會導致Infinity Loop呢?
            getLocationWeather(lat, lng, unit).then(weather => {
                this.setState ({
                    ...weather,
                    masking: true
                }); alert(JSON.stringify(this.state.city));  
            });
        });

        if (this.props.units !== unit) {
            this.props.onUnitChange(unit);
        }

        setTimeout(() => {
            this.setState({
                masking: false
            });
        }, 600)
    }

發現原因

原來我在setState後面多打一個等於


    this.setState = ({
            lat: lat,
            lng: lng
        }, () => { ...

this.setState變成一個新的function,執行後面getLocationWeather的程式後,呼叫this.setState,結果就變成死循環了

這個發生的原因!

結語

在和Huli大大聊過後,發現自己的作品還不完整,還能添加更多的功能,也看到其他人的天氣作品,覺得自己還有一段很長的路要走。歡迎各位一起討論!

DEMO

這裡

參考連接

  1. https://developers.google.com/maps/documentation/javascript/tutorial?hl=zh-tw
  2. https://www.youtube.com/watch?v=Zxf1mnP5zcw
  3. https://code.tutsplus.com/tutorials/getting-started-with-react-and-jsx--cms-27352
  4. https://developers.google.com/maps/documentation/javascript/events?hl=zh-tw
  5. https://developers.google.com/maps/documentation/javascript/markers?hl=zh-tw
  6. https://developers.google.com/maps/documentation/javascript/examples/marker-remove?hl=zh-tw