Mapbox JS - 在父状态更新时以编程方式更新地图

Mapbox JS - Update map programatically when parent state updates

Gatsby 项目 - 尝试在更新具有所需路线的状态时突出显示 Mapbox 路线。

当前实施:

由于 mapbox 地图似乎只能在 useEffect 挂钩中正确加载,我看不到任何其他方法可以根据父项的 activeItem 显示弹出窗口。如果有其他选择,请告诉我!

我尝试过的方法:

当前代码:

const EmbeddedMap = ({ updateList, activeItem }) => {
  const mapContainerRef = useRef(null)
  const [list, setList] = useState([])

  useEffect(() => {    
    const map = new mapboxgl.Map({
      container: mapContainerRef.current,
      accessToken: process.env.GATSBY_MAPBOX_TOKEN,
      style: "mapbox://styles/mapbox/...",
      center: [-90.836, 51.134],
      zoom: 6,
    })

    const popup = new mapboxgl.Popup()

    const getUniqueFeatures = (array, comparatorProperty) =>
      array.filter(
        (v, i, a) =>
          a.findIndex(
            t =>
              t.properties[comparatorProperty] ===
              v.properties[comparatorProperty]
          ) === i
      )

    const updateMap = map => {
      const features = map.queryRenderedFeatures({ layers: ["data"] })
      if (features) {
        const uniqueFeatures = getUniqueFeatures(features, "post_id")
        setList(uniqueFeatures)
      }
    }

    map.on("load", () => {
      updateMap(map)

      map.on("movestart", () => {
        map.setFilter("data", ["has", "title"])
      })

      map.on("moveend", () => {
        updateMap(map)
      })

      map.on("mousemove", "data", e => {
        map.getCanvas().style.cursor = "pointer"
        const feature = e.features[0]
        setPopup(map, popup, feature)
      })

      map.on("mouseleave", "data", () => {
        map.getCanvas().style.cursor = ""
      })

      map.on("click", "data", e => {
        const feature = e.features[0]
        map.flyTo({
          center: feature.geometry.coordinates[0],
        })
        setPopup(map, popup, feature)
      })
    })

    return () => map.remove()
  }, [])

  return (
    <div>
      <EmbeddedMapStyled ref={mapContainerRef} />
    </div>
  )
}

改变我对 ref 的方法解决了问题:

const map = useRef(null)
map.current = new mapboxgl.Map({
      container: mapContainerRef.current,
      accessToken: process.env.GATSBY_MAPBOX_TOKEN,
      style: "mapbox://styles/data",
      center: [-114.836, 51.134],
      zoom: 6,
    })

然后我可以轻松地重用地图,例如:

map.current.flyTo({
      center: activeItem.startPoint,
    })