setState 不会重新渲染反应功能组件

时间:2020-12-27 19:10:41

标签: reactjs setstate react-leaflet

我正在获取用户的位置并将其设置为“onSuccess”函数的新状态, 该组件不会重新渲染。 在检查了很多之后,我看到 react 没有将其视为状态的变化,因为在这种情况下它是一个数组,并且它没有通过 react 的“相等”检查作为已更改的状态。 有了这个,我尝试过的一切都没有奏效。有什么想法吗?

import { useEffect, useState } from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";

export default function Map() {
  const [location, setLocation] = useState([52.234, 13.413]);

  const onSuccess = (position) => {
    let userLocation = [position.coords.latitude, position.coords.longitude];
    setLocation([...userLocation]);
  };

  useEffect(() => {
    if (!("geolocation" in navigator)) {
      alert("no Geolocation available");
    }
    navigator.geolocation.getCurrentPosition(onSuccess);
  }, []);
  console.log(location);
  return (
    <>
      <MapContainer
        className="leaflet-map"
        center={location}
        zoom={11}
        scrollWheelZoom={false}
      >
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <Marker position={[51.505, -0.09]}>
          <Popup>
            A pretty CSS3 popup. <br /> Easily customizable.
          </Popup>
        </Marker>
      </MapContainer>
    </>
  );
}

2 个答案:

答案 0 :(得分:2)

即使 MapContainer 道具如文档中所述发生更改,center 似乎也不会在安装后重新定位:

https://react-leaflet.js.org/docs/api-map

<块引用>

除了它的子项,MapContainer 的 props 是不可变的:在第一次设置后更改它们不会对 Map 实例或其容器产生影响。

您可以通过传递您在 MapContainer 更改时更改的 key 属性来强制替换 location,例如:

<MapContainer
    key={`${location[0]}-${location[1]}`}

或者调查 react-leaflet 中的其他选项,例如 useMap 以访问 Leaflet Map 实例并调用 map.setView(...) https://leafletjs.com/reference-1.7.1.html#map-setview

答案 1 :(得分:1)

您能否确认完全调用了 onSuccess?可能是 getCurrentPosition 遇到了错误,所以用两个参数调用它会很好:

navigator.geolocation.getCurrentPosition(onSuccess, onError);

您还应该在 onSuccess 依赖项中包含 useEffect

  useEffect(() => {
    if (!("geolocation" in navigator)) {
      alert("no Geolocation available");
    }
    navigator.geolocation.getCurrentPosition(onSuccess);
  }, [onSuccess]);

并且为了防止由于 getCurrentPosition 更改而多次调用 onSuccess,您还应该 useCallback 依赖于 setLocation

  const onSuccess = useCallback((position) => {
    let userLocation = [position.coords.latitude, position.coords.longitude];
    setLocation([...userLocation]);
  }, [setLocation]);