【问题标题】:@react-google-maps/api / Feature click event resets state@react-google-maps/api / 功能点击事件重置状态
【发布时间】:2021-06-20 02:10:30
【问题描述】:

我正在使用@react-google-maps/api,我正在尝试在 gmap 功能上设置点击事件,将其区域​​附加到 React 状态。

enter image description here

但每次我单击该功能时,似乎状态已设置为空数组(初始状态)。并且事件将一个字符串附加到它。所以状态不会变长。

在这个组件中,我放置了一个按钮来触发相同的点击事件并且工作正常。我不知道为什么会这样。

const MapComponent = ({area, setArea}) => {

    const { isLoaded, loadError } = useLoadScript({
        googleMapsApiKey: "APIKEY"
    })

    const onClickFeature = e => {
        let tgt = e.feature.getProperty("S_NAME")
        if(tgt){
            addArea(tgt)
        }
    }

    const addArea = tgt => {
        let copy = [...area]
        copy.push(tgt)
        setArea(copy)
    }

    const renderMap = () => {

        const onLoad = async map => {
            await getGeoJson().then(res => {
                initPolygon(map,res) //draw polygons with feature collection
                map.data.addListener("click", e => {
                 onClickFeature(e)
                })
            })
        }

        return <><GoogleMap
            mapContainerStyle={containerStyle}
            center={center}
            zoom={14}
            onLoad={onLoad}
            onClick={onClickFeature}
            >
                
            </GoogleMap>
            <button onClick={() => addArea('someplace')}>CLICK</button> {/* This works fine */}
            
            <div>Selected: {area} </div>
    </>}

    if (loadError) {
        return <div>Map cannot be loaded right now, sorry.</div>
      }
    
    return isLoaded ? renderMap() : null
}

【问题讨论】:

  • 您能提供到目前为止您的代码的 [sscce](sscce.org) 吗?您可以使用stackblitz 来执行此操作。

标签: reactjs google-maps-api-3 react-hooks


【解决方案1】:

我可以看到您的用例应该有一个区域状态,应该是一个数组,并且每次单击 geoJsondata 功能时,它都会获得“S_NAME”属性的值。然后将其添加到区域状态数组中。

由于您尚未提供完整代码,因此我使用 Google Maps sample geojson data 创建了您的用例。每次点击该功能时,都会获取“title”属性并将其添加到“area”状态。

这里是sample code(注意:请在 index.js 中使用您的 API 密钥以使代码正常工作)和下面的代码 sn-p:

import React, { useState } from 'react';
import { GoogleMap } from '@react-google-maps/api';

const defaultLocation = { lat: -28, lng: 137 };

function Map() {
  const [area, setArea] = useState([]);

  const handleOnLoad = map => {
    map.data.loadGeoJson(
      'https://storage.googleapis.com/mapsdevsite/json/google.json'
    );
    map.data.addListener('click', onClickFeature);
  };

  const onClickFeature = event => {
    console.log(event.feature.getProperty('letter'));
    let letter = event.feature.getProperty('letter');
    if (letter) {
      addArea(letter);
    }
  };

  const addArea = letter => {
    let copy = area;
    copy.push(letter);
    setArea(copy);
//you will see here that the value of area array is being updated
    console.log(area);
  };

  return (
    <GoogleMap
      center={defaultLocation}
      zoom={5}
      onLoad={handleOnLoad}
      mapContainerStyle={{ width: '100%', height: '88vh' }}
    />
  );
}

export default Map;

【讨论】:

  • 感谢您回答我的非结构化问题(很抱歉回复晚了),但我还是听不懂。这是我的整个代码 sn-p:stackblitz.com/edit/react-49szfv?file=src/App.js,您会看到问题所在。 (毕竟我实际上是用 vanilla js 实现了这个项目)
  • 您的代码中的问题似乎在const addArea 尤其是在这部分=> let copy = [...area],因为您将区域的状态设置为数组(const [area, setArea] = useState([])),所以您不需要当您将其分配给变量副本时,将该区域放在[] 内。检查此sample code out。这都适用于多边形和按钮。您会注意到console.log(area) 现在将在您将其从tgt 推送到copy 后立即显示来自多边形的单击值。
  • 现在我看到它有效。似乎我对“不改变状态”规则很着迷,这就是我设置copy = [...area] 的原因。但是不就是变异状态,直接引用let copy = area; copy.push(letter)吗?
猜你喜欢
  • 2015-03-06
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 2023-02-04
  • 1970-01-01
相关资源
最近更新 更多