uiwjs / react-amap

基于 React 封装的高德地图组件,帮助你轻松的接入地图到 React 项目中。
https://uiwjs.github.io/react-amap
MIT License
417 stars 69 forks source link

ReferenceError: AMap is not defined #45

Closed majian159 closed 3 years ago

majian159 commented 3 years ago
import {
    APILoader, ControlBarControl, Geolocation, Map, Marker, ScaleControl, ToolBarControl
} from '@uiw/react-amap';

        <APILoader akay="a7a90e05a37d3f6bf76d4a9032fc9129">
          <Map>
            <ScaleControl offset={[16, 30]} position="LB" />
            <ToolBarControl offset={[16, 10]} position="RB" />
            <ControlBarControl offset={[16, 180]} position="RB" />
            <Geolocation
              maximumAge={100000}
              borderRadius="5px"
              position="RB"
              offset={[16, 80]}
              zoomToAccuracy={true}
              showCircle={true}
            />
            <Marker
              title="北京市"
              position={new AMap.LngLat(116.405285, 39.904989)}
            />
          </Map>
        </APILoader>
WeChat70fecc3df7f2811c927814ae9a346ce9
jaywcjlove commented 3 years ago

@majian159 组件 <APILoader> 是自动判断是否加载 高德地图 SDK,如果全局存在 AMap 对象就不加载 SDK,加载完成之后,全局将会有 window.AMap 对象。<APILoader> 再去加载 子组件

你的实例直接去使用 AMap 对象,SDK 都没有开始加载,所以直接报错的。 解决方案是分开写

const Demo = () => (
  <div style={{ width: '100%', height: '300px' }}>
      <ScaleControl offset={[16, 30]} position="LB" />
      <ToolBarControl offset={[16, 10]} position="RB" />
      <ControlBarControl offset={[16, 180]} position="RB" />
      <Geolocation
        maximumAge={100000}
        borderRadius="5px"
        position="RB"
        offset={[16, 80]}
        zoomToAccuracy={true}
        showCircle={true}
      />
      <Marker
        title="北京市"
        position={new AMap.LngLat(116.405285, 39.904989)}
      />
  </div>
);
ReactDOM.render((
  <APILoader akay="a7a90e05a37d3f6bf76d4a9032fc9129">
    <Demo />
  </APILoader>
), _mount_);

如果你非要写在一起,可以参考如下实例

<div style={{ width: '100%', height: '300px' }}>
  <Map center={[116.397428, 39.90923]} zoom={12}>
    {({ AMap, map, container }) => {
      console.log('map', map)
      if (map) {
        const marker = new AMap.Marker({
          icon: new AMap.Icon({
            imageSize: new AMap.Size(25, 34),
            image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png'
          }),
          position: [116.405285,39.904989],
          offset: new AMap.Pixel(-13, -30)
        });
        marker.setMap(map);
      }
      return;
    }}
  </Map>
</div>
majian159 commented 3 years ago

谢谢

jifenqi commented 3 years ago
const Mark = ({AMap})=>{
    return (
        <>
           {
                arr.map(({x,y},index)=>{
                    let lnglat = new AMap.LngLat(x,y)
                    console.log(x,y,lnglat)
                    return <Marker visiable={true} title="北京市" key={index} position={ lnglat } />
                })
            }
        </>
    )
}
<APILoader akay="a7a90e05a37d3f6bf76d4a9032fc9129">
            <div style={{ width: '100%', height: '100%' }}>
                <Map zoom={4}>
                    <Mark />
                </Map>
            </div>
</APILoader>

没有报错,也没有点标记哎,怎么回事呀

jaywcjlove commented 3 years ago

@jifenqi Map 组件是其他组件的基础,Map 组件会给所有的子组件注入两个属性 mapBMap

const Mark = ({AMap})=>{
    return (
        <>
           {
                arr.map(({x,y},index)=>{
                    let lnglat = new AMap.LngLat(x,y)
                    console.log(x,y,lnglat)
                    return (
                        <Marker
+                        AMap={AMap}
+                        map={map}
                        visiable={true} title="北京市" key={index} position={ lnglat } />
                    )
                })
            }
        </>
    )
}

如果还不行,可以使用 https://codesandbox.io/ 给我看一下你的实例

jifenqi commented 3 years ago

@jaywcjlove 能显示出来啦,谢谢

jaywcjlove commented 2 years ago

@lyquita 木有理解你的意思,你可以再包一层。

huiwi commented 1 year ago

@majian159 组件 <APILoader> 是自动判断是否加载 高德地图 SDK,如果全局存在 AMap 对象就不加载 SDK,加载完成之后,全局将会有 window.AMap 对象。<APILoader> 再去加载 子组件

你的实例直接去使用 AMap 对象,SDK 都没有开始加载,所以直接报错的。 解决方案是分开写

const Demo = () => (
  <div style={{ width: '100%', height: '300px' }}>
      <ScaleControl offset={[16, 30]} position="LB" />
      <ToolBarControl offset={[16, 10]} position="RB" />
      <ControlBarControl offset={[16, 180]} position="RB" />
      <Geolocation
        maximumAge={100000}
        borderRadius="5px"
        position="RB"
        offset={[16, 80]}
        zoomToAccuracy={true}
        showCircle={true}
      />
      <Marker
        title="北京市"
        position={new AMap.LngLat(116.405285, 39.904989)}
      />
  </div>
);
ReactDOM.render((
  <APILoader akay="a7a90e05a37d3f6bf76d4a9032fc9129">
    <Demo />
  </APILoader>
), _mount_);

如果你非要写在一起,可以参考如下实例

<div style={{ width: '100%', height: '300px' }}>
  <Map center={[116.397428, 39.90923]} zoom={12}>
    {({ AMap, map, container }) => {
      console.log('map', map)
      if (map) {
        const marker = new AMap.Marker({
          icon: new AMap.Icon({
            imageSize: new AMap.Size(25, 34),
            image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png'
          }),
          position: [116.405285,39.904989],
          offset: new AMap.Pixel(-13, -30)
        });
        marker.setMap(map);
      }
      return;
    }}
  </Map>
</div>

分开写以后还是报相同的错

jaywcjlove commented 1 year ago

@Garea-git 如果使用 https://codesandbox.io/embed/react-amap-example-y0n6c-y0n6c?fontsize=14&hidenavigation=1&theme=dark 能重现错误,我可以帮你看一下

huiwi commented 1 year ago

@Garea-git 如果使用 https://codesandbox.io/embed/react-amap-example-y0n6c-y0n6c?fontsize=14&hidenavigation=1&theme=dark 能重现错误,我可以帮你看一下

import React, { useState } from 'react'
import styles from './index.module.less'
import { Map, APILoader, Marker } from '@uiw/react-amap'
const Demo = () => {
  const [location, setLocation] = useState([120.499386, 28.047345])
  return (
    <>
      <div className={styles.container}>
        <Map style={{ height: '100%' }} center={location} >
          <Marker position={new AMap.LngLat(120.499386, 28.047345)} />
        </Map>
      </div>
      <div className={styles.showArea}>
        <div className={styles.btnArea}>
          <span className={styles.locationIcon} onClick={() => setLocation([120.499386, 28.047345])}>
            <svg t="1669188306055" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3177" width="128" height="128"><path d="M512 902.4a390.4 390.4 0 1 1 0-780.8 390.4 390.4 0 0 1 0 780.8z m0-64a326.4 326.4 0 1 0 0-652.8 326.4 326.4 0 0 0 0 652.8z" fill="#5A5A68" p-id="3178"></path><path d="M870.4 544a32 32 0 1 1 0-64h102.4a32 32 0 1 1 0 64h-102.4z" fill="#5A5A68" p-id="3179"></path><path d="M512 512m-204.8 0a204.8 204.8 0 1 0 409.6 0 204.8 204.8 0 1 0-409.6 0Z" fill="#5A5A68" p-id="3180"></path><path d="M544 153.6a32 32 0 1 1-64 0V51.2a32 32 0 1 1 64 0v102.4zM480 870.4a32 32 0 1 1 64 0v102.4a32 32 0 1 1-64 0v-102.4zM153.6 480a32 32 0 1 1 0 64H51.2a32 32 0 1 1 0-64h102.4z" fill="#5A5A68" p-id="3181"></path></svg>
          </span>
        </div>
        <div className={styles.card}>
          <div className={styles.title}>
            <img src="https://tse3-mm.cn.bing.net/th/id/OIP-C.y1l9vc1r9VreleEEUursrAHaHa?w=173&h=180&c=7&r=0&o=5&dpr=1.2&pid=1.7" alt="" />
            <div style={{ display: 'flex', flexDirection: 'column' }}>
              <span style={{ fontWeight: '600', marginBottom: '10px', fontSize: '2.133vw' }}>雅漾村-菜市场门口</span>
              <span style={{ fontSize: '1.867vw', color: 'rgb(38,69,189)' }}>设备编号:<span>1887578979</span></span>
            </div>
          </div>
          <div className={styles.info}>
            <div>
              <span>
                湿度:
                <span className={styles.number} style={{ color: 'rgb(0,196,171)' }}>45</span>
                <span className={styles.symbol}>%</span>
              </span>
            </div>
            <div>
              <span>
                温度:
                <span className={styles.number} style={{ color: 'rgb(251,84,70)' }}>45</span>
                <span className={styles.symbol}>°C</span>
              </span>
            </div>
            <div>
              <span>
                风速:
                <span className={styles.number} style={{ color: 'rgb(128,114,249)' }}>45</span>
                <span className={styles.symbol}>m/s</span>
              </span>
            </div>
          </div>
          <span className={styles.updateTime}>上次更新2022年11月20日 12:29</span>
        </div>
      </div>
    </>
  )
}
const MapInfo = () => {
  <APILoader akay="f1c02fdf004a4effdcd9a426d3687166">
    <Demo />
  </APILoader>
}
export default MapInfo

@jaywcjlove 这个是我的代码,麻烦帮我看看

jaywcjlove commented 1 year ago

@Garea-git 如果使用 https://codesandbox.io/embed/react-amap-example-y0n6c-y0n6c?fontsize=14&hidenavigation=1&theme=dark 能重现错误,我可以帮你看一下

huiwi commented 1 year ago

@Garea-git 如果使用 https://codesandbox.io/embed/react-amap-example-y0n6c-y0n6c?fontsize=14&hidenavigation=1&theme=dark 能重现错误,我可以帮你看一下

等会儿,我看一下这个怎么用,我不太懂

huiwi commented 1 year ago

https://codesandbox.io/embed/react-amap-example-react-17-forked-kgd45r?fontsize=14&hidenavigation=1&theme=light

@jaywcjlove

jaywcjlove commented 1 year ago

@Garea-git 代码错误

- const MapInfo = () => {
+ const MapInfo = () => (
  <APILoader akay="f1c02fdf004a4effdcd9a426d3687166">
    <Demo />
  </APILoader>
- }
+ )
jaywcjlove commented 1 year ago

@Garea-git https://codesandbox.io/embed/react-amap-example-react-17-forked-08ijel?fontsize=14&hidenavigation=1&theme=dark

huiwi commented 1 year ago

@Garea-git https://codesandbox.io/embed/react-amap-example-react-17-forked-08ijel?fontsize=14&hidenavigation=1&theme=dark

不是这个问题,我刚才代码写错了,但是改完后还是有报错

huiwi commented 1 year ago

这是我这个组件的代码

import React, { useState } from 'react'
import styles from './index.module.less'
import { Map, APILoader, Marker } from '@uiw/react-amap'
const Demo = () => {
  const [location, setLocation] = useState([120.499386, 28.047345])
  return (
    <>
      <div className={styles.container}>
        <Map style={{ height: '100%' }} center={location} >
          <Marker position={new AMap.LngLat(120.499386, 28.047345)} />
        </Map>
      </div>
      <div className={styles.showArea}>
        <div className={styles.btnArea}>
          <span className={styles.locationIcon} onClick={() => setLocation([120.499386, 28.047345])}>
            <svg t="1669188306055" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3177" width="128" height="128"><path d="M512 902.4a390.4 390.4 0 1 1 0-780.8 390.4 390.4 0 0 1 0 780.8z m0-64a326.4 326.4 0 1 0 0-652.8 326.4 326.4 0 0 0 0 652.8z" fill="#5A5A68" p-id="3178"></path><path d="M870.4 544a32 32 0 1 1 0-64h102.4a32 32 0 1 1 0 64h-102.4z" fill="#5A5A68" p-id="3179"></path><path d="M512 512m-204.8 0a204.8 204.8 0 1 0 409.6 0 204.8 204.8 0 1 0-409.6 0Z" fill="#5A5A68" p-id="3180"></path><path d="M544 153.6a32 32 0 1 1-64 0V51.2a32 32 0 1 1 64 0v102.4zM480 870.4a32 32 0 1 1 64 0v102.4a32 32 0 1 1-64 0v-102.4zM153.6 480a32 32 0 1 1 0 64H51.2a32 32 0 1 1 0-64h102.4z" fill="#5A5A68" p-id="3181"></path></svg>
          </span>
        </div>
        <div className={styles.card}>
          <div className={styles.title}>
            <img src="https://tse3-mm.cn.bing.net/th/id/OIP-C.y1l9vc1r9VreleEEUursrAHaHa?w=173&h=180&c=7&r=0&o=5&dpr=1.2&pid=1.7" alt="" />
            <div style={{ display: 'flex', flexDirection: 'column' }}>
              <span style={{ fontWeight: '600', marginBottom: '10px', fontSize: '2.133vw' }}>雅漾村-菜市场门口</span>
              <span style={{ fontSize: '1.867vw', color: 'rgb(38,69,189)' }}>设备编号:<span>1887578979</span></span>
            </div>
          </div>
          <div className={styles.info}>
            <div>
              <span>
                湿度:
                <span className={styles.number} style={{ color: 'rgb(0,196,171)' }}>45</span>
                <span className={styles.symbol}>%</span>
              </span>
            </div>
            <div>
              <span>
                温度:
                <span className={styles.number} style={{ color: 'rgb(251,84,70)' }}>45</span>
                <span className={styles.symbol}>°C</span>
              </span>
            </div>
            <div>
              <span>
                风速:
                <span className={styles.number} style={{ color: 'rgb(128,114,249)' }}>45</span>
                <span className={styles.symbol}>m/s</span>
              </span>
            </div>
          </div>
          <span className={styles.updateTime}>上次更新2022年11月20日 12:29</span>
        </div>
      </div>
    </>
  )
}
const MapInfo = () => {
  return (
    <APILoader akay="f1c02fdf004a4effdcd9a426d3687166">
      <Demo />
    </APILoader>
  )
}
export default MapInfo

然后我在App.js引用

import React from 'react'
import MapInfo from './MapInfo'
export default function App() {
  return (
    <>
      <MapInfo />
    </>
  )
}

image

jaywcjlove commented 1 year ago

@majian159 代码贴到示例里面啊

jaywcjlove commented 1 year ago

@Garea-git https://codesandbox.io/s/react-amap-example-react-18-uiwjs-react-amap-issues-45-08ijel

有什么问题?

image
huiwi commented 1 year ago

@Garea-git https://codesandbox.io/s/react-amap-example-react-18-uiwjs-react-amap-issues-45-08ijel

有什么问题?

image

刚才我看了一下确实好了,但是我改了一下marker的坐标,就又报错了

huiwi commented 1 year ago

image 我在CodeSandBox改了一下坐标,也会报错说'AMap' is not defined,但是页面可以正常显示,我在本机上改却没法正常显示 image

jaywcjlove commented 1 year ago

@majian159 这个是ESLint 的错误,在代码的顶部添加 /*global AMap*/ 错误就没有了,或者修改 ESLint 配置,如果用 TS,默认引入了类型包,不会报错。

AMap 对象是全局对象没有声明,它是通过 加载 地图SDK 完成后生成的全局对象

jaywcjlove commented 1 year ago
image
huiwi commented 1 year ago

@majian159 这个是ESLint 的错误,在代码的顶部添加 /*global AMap*/ 错误就没有了,或者修改 ESLint 配置,如果用 TS,默认引入了类型包,不会报错。

AMap 对象是全局对象没有声明,它是通过 加载 地图SDK 完成后生成的全局对象

ok,麻烦你了,谢谢

huiwi commented 1 year ago

@jaywcjlove 还有一个问题,我这里Marker的位置会随着地图的缩放改变是什么原因

jaywcjlove commented 1 year ago

@Garea-git 有问题新起一个 issue 讨论