はじめに
React × Google Mapsを使って地図アプリを作っていたとき、
supabaseからデータを取得した際、地図上のピンが更新されない
という現象に遭遇しました。
原因は、「Reactの再レンダー」と「Google Mapsの再描画」が
まったく別の仕組みで動いていることでした。
Reactが再レンダーしてもGoogle Mapsが変わらない理由
Reactは「仮想DOM(Virtual DOM)」を使ってUIを管理します。
つまり、Reactが更新できるのは 自分で作った要素だけ です。
一方、Google Mapsは
内部で new google.maps.Map() を呼び出し、
ブラウザのDOMを直接描画 しています。
この地図はReactの外で動いているため、
Reactのstateが変わっても自動で更新されません。
公式ドキュメントにも記載があります。
key を変えるとどうなる?
Reactには「key が変わると別コンポーネントとみなす」というルールがあります。
つまり、
<Map key={JSON.stringify(filters)} /> のように書くと、
filters が変わるたびに key も変化し、結果として、
<Map> が 再マウント(=再生成) され、
Google Mapsも最新状態で描き直されます。
一言でまとめると
Google MapsはReactの外で動くため、state変更では自動更新されない。
そのため、keyを変えて再マウントさせることで再描画を強制できる。
参考リンク
-
React公式: Reconciliation (Diffing Algorithm)
https://legacy.reactjs.org/docs/reconciliation.html -
@vis.gl/react-google-maps公式: Map Component Docs
https://visgl.github.io/react-google-maps/docs/api-reference/components/map -
Google Maps API: Overview
https://developers.google.com/maps/documentation/javascript/overview