reactjs - Vilka är de korrekta typerna för att mappa variabler med Mapbox i React?
Efter att ha tittat på Mapbox-dokumentationen skrev jag den här komponenten
import React from "react";
import mapboxgl from "mapbox-gl";
import "./Map.css";
mapboxgl.accessToken = "...";
type Props = {
longitude: number;
latitude: number;
};
class Map extends React.Component<Props> {
private mapContainer: any;
private map: any;
componentDidMount(): void {
this.map = new mapboxgl.Map({
container: this.mapContainer,
center: [this.props.longitude, this.props.latitude],
style: "....",
zoom: 13
});
}
render(): JSX.Element {
return (
<div
ref={(el): void => {
this.mapContainer = el;
}}
className="mapContainer"
/>
);
}
}
export default Map;
Denna kod fungerar korrekt, men i mitt verkliga projekt använder vi TypeScript. Jag vill inte använda any för mapContainer och map.
Jag har importerat "@types/mapbox-gl": "^1.7.0", till mitt projekt, men jag kan inte lista ut vilken typ jag måste använda här.
Mina försök hittills:
private map:mapboxgl.Map. Det verkar vara korrekt, men sedan klagar det eftersom det inte är initierat i konstruktorn. Enligt Mapbox-dokumentationen måste det initieras icomponentDidMount. Jag kan typa variabeln medmapboxgl.Map | null. Men då måste jag konstant kontrollera att den inte är null för att ta bort några irriterande varningar.private mapContainer=React.userRef<HtmlElement>(null);. Men när jag försöker initiera kartan säger det Typ'RefObject<HTMLElement>' kan inte tilldelas typ 'string | HTMLElement'.
Några idéer?
Svar #1
Baserat på din kod fungerar följande. Först behöver du importera Map-typen som exporteras från mapbox-gl:
import mapbox-gl, { Map } from "mapbox-gl";
Vilket senare kan användas som en typ för kartan inuti din komponent:
private map: Map | undefined; // | undefined is needed here otherwise Typescript will complain about a missing initialiser inside the constructor.
Nu kommer den knepiga delen, container definieras som:
container: string | HTMLElement
inne i MapboxOptions typdefinition. Därför måste vi kringgå det lite:
class SampleMap extends React.Component<Props> {
private mapContainer: HTMLElement | null | undefined = undefined;
private map: Map | undefined;
componentDidMount(): void {
this.map = new mapboxgl.Map({
container:
this.mapContainer === undefined || this.mapContainer === null
? "" // or pass in some other HTMLElement which is definitely defined or similar ...
: this.mapContainer,
... // abbreviated
});
}
render(): JSX.Element {
... // abbreviated
}
}
Det finns en kontroll om mapContainer är definierad och inte null och skickar in mapContainer, annars en string eller kanske kan du skicka in någon annan HTMLElement som du vet är 100% definierad. T.ex. document#root.
Fullständig kod kan hittas här: på CodeSandbox
