React-map-gl with axios - Error“Can't perform a React state update on an unmounted component”

wwwo4jvm  于 12个月前  发布在  iOS
关注(0)|答案(1)|浏览(108)

我已经在这个简单的文件3天,需要你的帮助。我是新的React,和MapBox太:)。
我需要使用一个API并将其显示在一个mapbox上。使用JSON(ANNONCE)一切正常,但使用useEffect(axios-asynchronous),我有一个类型的错误:“无法在未挂载的组件上执行React状态更新”。我认为这是一个计时错误(componentDidMount maybe),但我不知道如何解决它。你能帮助我吗?非常感谢。

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"));

字符串

zlwx9yxi

zlwx9yxi1#

我遇到了同样的问题。问题是来自API的纬度和经度值表示为字符串。将这些字符串坐标传递给Marker组件会导致初始错误,然后导致一连串令人困惑的消息。
因此,虽然最后一个错误指出您不能更新未装载组件的状态,但真实的原因是一个简单的类型错误。

相关问题