如何强制react-map-gl地图在道具更改时重新渲染

问题描述 投票:0回答:1

我在我的项目中使用了react-map-gl

Map
组件。我通过 props
props.displayUploadedFiles
传入,这是一组 GeoJSON 对象。我想使用react-map-gl 的
Map
Source
组件在我的
Layer
上显示这些 GeoJSON 对象。但是,当我上传文件时,查看地图上文件中的数据的唯一方法是移动/平移地图以强制重新渲染。

我希望我可以使用一个钩子来表示“当这个道具发生变化时,更改我的地图中的源和图层并显示它们。”然而,钩子似乎没有立即显示,而是在我平移地图之前不会触发。

我可以确认文件已上传且采用正确的 GeoJSON 格式,并且传递到

Map
组件的 props 会随着 props 的更新而更新。

以下是 props 传递方式的示例:

// App.tsx
export default function App(): JSX.Element {
  const [files, setFiles] = useState<any[]>([]);
  const setFilesState = (filesUploaded: File[]) => {
    const jsons = kmlToGeoJson(filesUploaded);
    setFiles(jsons);
  };

  return (
    <>
      <MyMap displayUploadedFiles={files} ... />
      <MyFileUploader fileStateUpdater={setFilesState} />
    </>
  );
}

//MyMap.tsx
function MapboxMap(props: MapboxMapProps): JSX.Element {
  const geoJsons = useMemo(() => (props.displayUploadedFiles.map((file) => {
    const id = JSON.stringify(file.features);
    return (
      <Source key={id} type="geojson" data={file}>
        <Layer key={id} {...pointLayer} />
      </Source>
    );
  })), [JSON.stringify(props.displayUploadedFiles)]); // runs on upload once I move the map

  return (
    <Map mapboxAccessToken={mapboxToken} ...>
      {geoJsons}
      ...
    </Map>
  );
}

function MyMap(props: StyledMapProps): JSX.Element {
  return (
    <div id={sx.styledMap}>
      <MapboxMap ... displayUploadedFiles={props.displayUploadedFiles} />
      ...
  );
}

export default MyMap;


这篇文章似乎与我的问题非常相似,但针对的是基于类的设计而不是功能设计。它表明我应该使用

useEffect()
。然而,我无法让它发挥作用——它的行为与我上面描述的相同。最小的例子有
useMemo()
,因为我也尝试过。

最小的示例还将

useMemo()
依赖项显示为
[JSON.stringify(props.displayUploadedFiles)]
,因为我认为仅传入数组可能就是问题所在,因为即使内容发生变化,引用也可能不会改变,这意味着它不会重新使成为。然而,这并没有改变行为。

我还尝试更改

MyFileUploader
的位置,以便道具不是从 App.tsx 传递,而是将逻辑包含在
MyMap
MapboxMap
中,但它们不会改变行为。在任何情况下,道具总是正确更新,但依赖于它的钩子在我平移地图之前不会被调用。

reactjs react-hooks mapbox-gl-js react-map-gl
1个回答
0
投票

您可以使用

useEffect
来观察道具的变化并触发地图图层的更新。您还可以使用
useMemo
钩子来记忆
geoJsons
数组,以提高性能。

import React, { useState, useEffect, useMemo } from 'react';
import { Map, Source, Layer } from 'react-map-gl';

function MapboxMap(props) {
  const geoJsons = useMemo(() => (
    props.displayUploadedFiles.map((file) => {
      const id = JSON.stringify(file.features);
      return (
        <Source key={id} type="geojson" data={file}>
          <Layer key={id} {...pointLayer} />
        </Source>
      );
    })
  ), [props.displayUploadedFiles]);

  // Use useEffect to trigger the map update when props change
  useEffect(() => {
    // Force a map update when the displayUploadedFiles prop changes
    // This will re-render the map layers immediately
    // You may also need to handle map updates here if required
  }, [props.displayUploadedFiles]);

  return (
    <Map mapboxAccessToken={mapboxToken} ...>
      {geoJsons}
      {/* ... */}
    </Map>
  );
}

export default MyMap;

现在,当

displayUploadedFiles
属性发生变化时,它应该立即更新,而不需要平移地图。

© www.soinside.com 2019 - 2024. All rights reserved.