【问题标题】:What are the correct types to map variables using Mapbox in React?在 React 中使用 Mapbox 映射变量的正确类型是什么?
【发布时间】:2020-02-20 14:50:36
【问题描述】:

看了mapbox documentation之后,写了这个组件

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;

此代码可以正常工作,但是,在我的实际项目中,我们使用的是 TypeScript。我不想将any 用于mapContainermap

我已将"@types/mapbox-gl": "^1.7.0", 导入到我的项目中,但我不知道我必须在这里使用什么类型。

到目前为止我的尝试:

  • private map:mapboxgl.Map。这似乎是正确的,但后来它抱怨,因为它没有在构造函数上初始化。根据 mapbox 文档,它必须在 componentDidMount 上初始化。我可以用mapboxgl.Map | null 输入变量。但后来我必须检查 constally 不为空,删除 一些烦人的警告。
  • private mapContainer = React.userRef&lt;HtmlElement&gt;(null);。但是,当我尝试初始化地图时,它显示 Type 'RefObject&lt;HTMLElement&gt;' is not assignable to type 'string | HTMLElement'.

有什么想法吗?

【问题讨论】:

  • 对于this.map,使用:this.map: Map,通过为mapContainer 导入import { Map } from "@types/mapbox-gl",您可以尝试使用HtmlElement 而不是HtmlDivElement
  • HtmlElement 似乎是正确的,但是当我尝试初始化地图时它会抱怨。

标签: reactjs typescript mapbox mapbox-gl


【解决方案1】:

根据您的代码,以下工作。首先,您需要导入从mapbox-gl 导出的Map 类型:

import mapbox-gl, { Map } from "mapbox-gl";

稍后可以用作组件内地图的类型:

private map: Map | undefined; // | undefined is needed here otherwise Typescript will complain about a missing initialiser inside the constructor.

现在是棘手的部分,容器定义为:

container: string | HTMLElement

在 MapboxOptions 类型定义中。因此,我们必须稍微解决它:

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
  }
}

检查mapContainer 是否已定义且不为空并传入mapContainer 否则为string 或者您可以传入其他一些您知道100% 已定义的HTMLElement。例如。 document#root.

完整的代码可以在这里找到:on CodeSandbox

【讨论】:

  • 感谢您的帮助。它按预期工作。但我有点担心。在 componentDidMount 中初始化它的地图。但是,在componentDidUpdate 中使用this.map 会显示一个抱怨,因为is posible undefined。要删除警告,我必须检查this.map !== undefined。但这不是必需的,因为componentDidUpdate 总是在 didMount 之后执行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-22
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2021-08-01
相关资源
最近更新 更多