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

wwwo4jvm  于 2024-01-07  发布在  iOS
关注(0)|答案(1)|浏览(136)

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

  1. import "mapbox-gl/dist/mapbox-gl.css";
  2. import "react-map-gl-geocoder/dist/mapbox-gl-geocoder.css";
  3. import React, {PureComponent, useCallback, useEffect, useRef, useState, } from "react";
  4. import {render} from "react-dom";
  5. import MapGL, {Marker} from "react-map-gl";
  6. import Geocoder from "react-map-gl-geocoder";
  7. import axios from 'axios'
  8. const MAPBOX_TOKEN =
  9. '';
  10. const ANNONCE = [
  11. {
  12. "@id": "/api/announces/12",
  13. "@type": "Announce",
  14. "subject": "Sujet essaicatogrie",
  15. "duration": 3,
  16. "gratis": true,
  17. "lat": 48.17,
  18. "lon": 4.23
  19. },
  20. {
  21. "@id": "/api/announces/13",
  22. "@type": "Announce",
  23. "subject": "Marche sur les terrils",
  24. "duration": 2,
  25. "gratis": true,
  26. "lat": 47.02,
  27. "lon": -0.71
  28. },
  29. {
  30. "@id": "/api/announces/14",
  31. "@type": "Announce",
  32. "subject": "footing en montagne",
  33. "duration": 2,
  34. "gratis": false,
  35. "lat": 46.27,
  36. "lon": 3.67
  37. },
  38. {
  39. "@id": "/api/announces/15",
  40. "@type": "Announce",
  41. "subject": "Kayak sur la loire",
  42. "duration": 4,
  43. "gratis": false,
  44. "lat": 44.45,
  45. "lon": 1.06
  46. }
  47. ]
  48. class Markers extends PureComponent {
  49. render() {
  50. const {data} = this.props;
  51. return data.map(
  52. city =>
  53. <Marker key={city.id} longitude={city.lon} latitude={city.lat}>
  54. <img src='http://placekitten.com/200/300'/>
  55. </Marker>
  56. )
  57. }
  58. }
  59. /* *********************************************************/
  60. const useDataApi = (initialUrl, initialData) => {
  61. const [data, setData] = useState(initialData);
  62. const [url, setUrl] = useState(initialUrl);
  63. const [items, setItems] = useState([])
  64. const [count ,setCount]= useState(0)
  65. const [isLoading, setIsLoading] = useState(false);
  66. const [isError, setIsError] = useState(false);
  67. const isMountedRef = useRef(null);
  68. useEffect(() => {
  69. isMountedRef.current = true;
  70. const fetchData = async () => {
  71. setIsError(false);
  72. setIsLoading(true);
  73. try {
  74. const result = await axios(url);
  75. setData(result.data);
  76. setItems(result.data['hydra:member'])
  77. setCount(result.data['hydra:totalItems'])
  78. } catch (error) {
  79. setIsError(true);
  80. }
  81. setIsLoading(false);
  82. };
  83. fetchData();
  84. }, [url]);
  85. return [{ items,count,data, isLoading, isError }, setUrl];
  86. };
  87. /* *********************************************************/
  88. const App = () => {
  89. const [query, setQuery] = useState('');
  90. const [{ items,count,data, isLoading, isError }, doFetch] = useDataApi(
  91. '/api/announces/',
  92. { hits: [] },
  93. );
  94. const [viewport, setViewport] = useState({
  95. latitude: 46.5,
  96. longitude: 2.3,
  97. zoom: 5
  98. });
  99. const mapRef = useRef();
  100. const handleViewportChange = useCallback(
  101. (newViewport) => setViewport(newViewport),
  102. []
  103. );
  104. /************************ GEOCODER **********************/
  105. const handleGeocoderViewportChange = useCallback(
  106. (newViewport) => {
  107. const geocoderDefaultOverrides = {transitionDuration: 1000};
  108. return handleViewportChange({
  109. ...newViewport,
  110. ...geocoderDefaultOverrides
  111. });
  112. },
  113. [handleViewportChange]
  114. );
  115. /***************************************************/
  116. return (
  117. <div className="map-wrapper">
  118. <MapGL
  119. ref={mapRef}
  120. {...viewport}
  121. width="100%"
  122. height="100%"
  123. onViewportChange={handleViewportChange}
  124. mapStyle="mapbox://styles/mapbox/streets-v11"
  125. mapboxApiAccessToken={MAPBOX_TOKEN}>
  126. <Geocoder
  127. mapRef={mapRef}
  128. onViewportChange={handleGeocoderViewportChange}
  129. mapboxApiAccessToken={MAPBOX_TOKEN}
  130. position="top-left"
  131. />
  132. <Markers data={items} // <------ I NEED TO CHANGE THIS IN "items" (axios - api)
  133. />
  134. </MapGL>
  135. </div>
  136. );
  137. };
  138. render(<App/>, document.getElementById("idmap"));

字符串

zlwx9yxi

zlwx9yxi1#

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

相关问题