小贴士

1. 受控组件

amap-react 中大多数组件都是受控组件,你需要用一组典型的value/onChange模式来管理这些 props。

例如,如果你需要设置地图中心点和缩放级别,则可以使用类似下面的代码来实现

const [zoom, setZoom] = useState(10);
const [center, setCenter] = useState([116.473571, 39.993083]);
return (
<Amap
zoom={zoom}
center={center}
onZoomChange={(map) => setZoom(map.getZoom())}
onMapMove={(map) => setCenter(map.getCenter().toArray())}
/>
);

具体例子可以参考受控组件

2. 使用 amap-react 未封装的 props

由于版本更新难以完全同步,amap-react 未能覆盖所有的 AMap JSAPI 的属性,你可能有不同场景需要传入或者修改 AMap 组件的某些参数

2.1. 作为初始化参数

如果你需要将尚未支持的参数作为 AMap 组件的初始化属性传入,可以将其放入extraOptions属性中,例如

<Amap extraOptions={{ someNewMapOptions: value }}>
<Marker extraOptions={{ someNewMarkerOptions: anotherValue }} />
</Amap>

2.2. 运行中获取或者修改 AMap 组件的属性

如果要在运行中读取或者修改 AMap 组件的属性,可以通过ref拿到 AMap 组件对象,或者通过useAmap拿到地图对象,再调用你需要的getter/setter

具体使用方法可以参考获取组件 ref扩展自定义组件

3. 性能优化

如果你需要展现的地图元素较少,例如几个或者几十个点、线、面,你可以直接通过 React 组件方式,循环生成点、线、面等组件。这样你可以像使用普通的 React 组件一样去给它们绑定数据、事件,并且根据数据的变化随时去更新它们。即使对于 AMap JSAPI 的 API 并不是非常熟悉,也可以开发一些基于地图的业务场景。

例如LabelMarker小区排行的例子,就是简单地将数组循环映射成<LabelMarker><Polygon>

如果你需要展现的地图元素很多,例如你需要展示数千乃至数万的点,使用上述的方式则会产生大量的 React 组件实例。这样除了会造成 React Virtual DOM 压力剧增以外,如此多的组件去维护各自对应的 AMap 组件实例所带来的额外开销也很大,页面的初始渲染和更新会变得非常卡顿。

如果遇到这种情况,建议你不要再循环生成大量的组件实例,而是将数据的管理和应用封装在单个组件内部,例如大量 LabelMarker。除了散点图,你也可以考虑更多的展现方式,比如热力图点聚合WebGL 绘制,或者将数据按行政区聚合后再展示各省 GDP 增速可视化

4. 响应地图事件

你可以在子组件中,使用useAmapEvents来自动绑定/解绑AMap.Map的事件,具体用法可以参考这个例子

5. 我该使用<Marker>还是<LabelMarker>

对比维度<Marker><LabelMarker>
性能几十 ~ 几百个点成千上万个点(不开启避让)
样式复杂 - 可自定义 DOM 和 CSS简单 - 图标 + 文字
聚合通过使用<MarkerCluster>组件
可以支持复杂的聚合
通过配置collision=true参数
可以支持避让
移动通过加载AMap.MoveAnimation插件
可以支持moveTomoveAlong
不支持,需要自行实现
事件丰富简单

6. 我该使用<Circle>还是<CircleMarker>

对比维度<Circle><CircleMarker>
半径单位米(展现的大小随地图缩放)像素(不受地图缩放影响)
样式不支持strokeStylestrokeDasharray(虚线边框)支持几乎所有的“面”类型样式
交互性<Polygon>类似,可以通过<CircleEditor>来编辑<Marker>类似

<CircleMarker>不支持虚线边框,我非要展示一个带虚线边框的、以像素为单位的圆,该怎么办?

  • 制作带虚线边框的圆形png或svg图片资源
  • 通过<Marker><LabelMarker>来展现