单击按钮显示 GeoJSON class 的新 geojson 数据

Display new geojson data for GeoJSON class on click of button

我正在使用 React 传单库。特别是,我使用库附带的 GeoJSON class 来呈现由 geojson 描述的地图。目前我的 class 看起来像这样:

const MyMap = () => {
    const [stateGeoJSON, setStateGeoJSON] = useState(exampleGeoJSON)
    
    const setStateGeoJSON = (newJson) => {
        setStateGeoJSON(newJson)
    }
    
    return (
        <div>
            <MapContainer
                style={{ height: '90vh'}}
                zoom={zoom}
                maxZoom={12}
                minZoom={5}
                center={mapCenter}
                zoomControl={false}
                maxBounds={mapCenter}
                maxBoundsViscosity={1.0}
            >
                <StateMap geojson={stateGeoJSON}/>
            </MapContainer>
        </div>
    )
}

我还有一个名为 StateMap 的 class,它位于 MyMap class 内部,看起来像这样:

const StateMap = ({ geojson }) => {
    return (
        <div>
            <GeoJSON
                style={districtStyleDefault}
                data={geojson.features}
                onEachFeature={onEachState}
            />
        </div>
    )
}

我没有在 post 中放置函数“onEachFeature”或样式,但它们在那里。基本上,我的 StateMap class 从 MyMap 中获取一个名为“geojson”的道具,这是将用于在 StateMap 中呈现地图的 geojson。这一切都有效。

问题是我试图通过单击按钮来更改在 StateMap 内部使用的 geojson。用户单击按钮后,将使用新的 geojson 调用 setStateGeoJSON。然后更改名为“stateGeoJSON”的状态变量。我认为这会更新 StateMap 中的 GeoJSON 组件,但事实并非如此。我还尝试在 StateMap 中创建状态变量,当道具“geojson”发生变化时会发生变化,但这也不会改变正在使用的 geojson。我不确定如何解决这个问题。如有任何帮助,我们将不胜感激。

如果你看一下 react-leaflet docs for GeoJSON,你会发现 data 属性 不可变,意思是GeoJSON 组件在创建后不会响应 data 属性的更改。这是 react-leaflet v3 的一个新特性,它在库中随处可见,有助于避免不必要的 react 组件重新渲染。

因此,要更改数据,您需要获取对底层传单元素的引用,然后从那里开始,就像在原始传单应用程序中一样。

const StateMap = ({ geojson }) => {

    // get a ref to the underlying L.geoJSON
    const geoJsonRef = useRef()

    // set the data to new data whenever it changes
    useEffect(() => {
      if (geoJsonRef.current){
        geoJsonRef.current. clearLayers()   // remove old data
        geoJsonRef.current.addData(geojson) // might need to be geojson.features
      }
    }, [geoJsonRef, geojson])

    return (
        <div>
            <GeoJSON
                ref={geoJsonRef}
                style={districtStyleDefault}
                data={geojson.features}
                onEachFeature={onEachState}
            />
        </div>
    )
}