mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.2k stars 2.22k forks source link

How to render a map using React functional components and typescript #9395

Closed bitofbreeze closed 4 years ago

bitofbreeze commented 4 years ago

mapbox-gl version: 1.8.1 @types/mapbox-gl version: 1.8.0

Question

Here's an attempt:

function App() {
  const container = <div></div>;
  const map = new mapboxgl.Map({
    container,
    style: "mapbox://styles/mapbox/streets-v11",
    center: [5, 34],
    zoom: 2
  });
  return <>{container}</>;
}

But I get Error: Invalid type: 'container' must be a String or HTMLElement..

'container' is actually a jsx Element here.

Have tried a few other things like casting and such but no dice.

Can't seem to find any docs on how to do this.

Links to related documentation

https://docs.mapbox.com/help/tutorials/use-mapbox-gl-js-with-react/

bitofbreeze commented 4 years ago

figured it out using refs https://github.com/mapbox/mapbox-react-examples/blob/master/basic/src/index.js

auxcoder commented 4 years ago

I had the same issue migrating the Component based example to FC and ended with something like this.

import React, {useEffect} from 'react';
import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = 'yourAccessToken';
type Props = {}; // add your props
const MapPage: React.FC<Props> = (props) => {
  let mapRef: HTMLDivElement | null;
  useEffect(() => {
    if (mapRef) {
      const map = new mapboxgl.Map({
        container: mapRef,
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-122.420679, 37.772537],
        zoom: 15,
      });
    }
  }, []);
  return (
    <div id="mapPage">
      <div id="map" ref={el => mapRef = el}/>
    </div>
  );
};
export default MapPage;