带有 axios 的 React-map-gl - 错误“无法在未安装的组件上执行 React 状态更新”

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

我处理这个简单的文件已经三天了,需要你的帮助。 我是 React 新手,也是 MapBox 新手:)。

我需要使用 api 并将其显示在地图框上。 使用 JSON (ANNONCE) 一切正常,但使用 useEffect(axios-asynchronous) 时,出现以下类型的错误: “无法对未安装的组件执行 React 状态更新”。我认为这是一个计时错误(可能是 componentDidMount),但我不知道如何解决它。 你可以帮帮我吗?非常感谢。

    import "mapbox-gl/dist/mapbox-gl.css";
import "react-map-gl-geocoder/dist/mapbox-gl-geocoder.css";
import React, {PureComponent, useCallback, useEffect, useRef, useState, } from "react";
import {render} from "react-dom";
import MapGL, {Marker} from "react-map-gl";
import Geocoder from "react-map-gl-geocoder";
import axios from 'axios'


const MAPBOX_TOKEN =
  '';

const ANNONCE = [
  {
    "@id": "/api/announces/12",
    "@type": "Announce",
    "subject": "Sujet essaicatogrie",
    "duration": 3,
    "gratis": true,
    "lat": 48.17,
    "lon": 4.23

  },
  {
    "@id": "/api/announces/13",
    "@type": "Announce",
    "subject": "Marche sur les terrils",
    "duration": 2,
    "gratis": true,
    "lat": 47.02,
    "lon": -0.71
  },
  {
    "@id": "/api/announces/14",
    "@type": "Announce",
    "subject": "footing en montagne",
    "duration": 2,
    "gratis": false,
    "lat": 46.27,
    "lon": 3.67
  },
  {
    "@id": "/api/announces/15",
    "@type": "Announce",
    "subject": "Kayak sur la loire",
    "duration": 4,
    "gratis": false,
    "lat": 44.45,
    "lon": 1.06
  }
]
class Markers extends PureComponent {
  render() {
    const {data} = this.props;

    return data.map(
      city =>
        <Marker key={city.id} longitude={city.lon} latitude={city.lat}>
          <img src='http://placekitten.com/200/300'/>
        </Marker>
    )
  }
}
/* *********************************************************/
const useDataApi = (initialUrl, initialData) => {
  const [data, setData] = useState(initialData);
  const [url, setUrl] = useState(initialUrl);
  const [items, setItems] = useState([])
  const [count ,setCount]= useState(0)
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  const isMountedRef = useRef(null);


  useEffect(() => {
    isMountedRef.current = true;

    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);

      try {
        const result = await axios(url);

        setData(result.data);
        setItems(result.data['hydra:member'])
        setCount(result.data['hydra:totalItems'])

      } catch (error) {
        setIsError(true);

      }

      setIsLoading(false);
    };

    fetchData();
  }, [url]);

  return [{ items,count,data, isLoading, isError }, setUrl];
};

/* *********************************************************/

const App = () => {
  const [query, setQuery] = useState('');

  const [{ items,count,data, isLoading, isError }, doFetch] = useDataApi(
    '/api/announces/',
    { hits: [] },
  );
  const [viewport, setViewport] = useState({
    latitude: 46.5,
    longitude: 2.3,
    zoom: 5
  });

  const mapRef = useRef();
  const handleViewportChange = useCallback(
    (newViewport) => setViewport(newViewport),
    []
  );


  /************************  GEOCODER **********************/
  const handleGeocoderViewportChange = useCallback(
    (newViewport) => {
      const geocoderDefaultOverrides = {transitionDuration: 1000};

      return handleViewportChange({
        ...newViewport,
        ...geocoderDefaultOverrides
      });
    },
    [handleViewportChange]
  );
  /***************************************************/

  return (
    <div className="map-wrapper">
      <MapGL
        ref={mapRef}
        {...viewport}
        width="100%"
        height="100%"
        onViewportChange={handleViewportChange}
        mapStyle="mapbox://styles/mapbox/streets-v11"
        mapboxApiAccessToken={MAPBOX_TOKEN}>

        <Geocoder
          mapRef={mapRef}
          onViewportChange={handleGeocoderViewportChange}
          mapboxApiAccessToken={MAPBOX_TOKEN}
          position="top-left"
        />
        <Markers data={items}  // <------ I NEED TO CHANGE THIS IN "items" (axios - api)

        />
      </MapGL>
    </div>
  );
};

render(<App/>, document.getElementById("idmap"));
reactjs asynchronous axios mapbox react-map-gl
2个回答
1
投票

我遇到了同样的问题。问题在于来自 API 的纬度和经度值被表示为字符串。将这些字符串坐标传递给 Marker 组件会导致最初的错误,进而导致一系列令人困惑的消息。

因此,虽然最终错误表明您无法更新已卸载组件上的状态,但真正的原因是一个简单的类型错误。


0
投票

有趣!我想我也有同样的问题。这个问题解决了吗?

react-map-gl不从djangorest框架json响应中绘制引脚

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