正在从 websocket 获取数据以进行实时更新,正在更新传单地图的内部弹出窗口,useEffect 开始重新渲染以获取新数据,以便弹出窗口消失,我需要再次单击地图上的标记才能查看更新的数据,我想要的就是数据发生变化而弹出窗口不会消失。 这是名为 Positions 的组件的代码,它携带地图上数据和标记的更改。
import React, { useEffect, useState } from "react";
import { useGetAllPositionsQuery } from "../../Redux/service/Positions";
import MarkerClusterGroup from "react-leaflet-cluster";
import { Marker, Popup } from "react-leaflet";
import { Icon } from "leaflet";
import PositionsPopups from "./Positions-Popups/PositionsPopups";
import { useGetWebSocketDataQuery } from "../../Redux/service/Websocket";
export default function Positions() {
const { data, isLoading } = useGetAllPositionsQuery();
let [position, setPosition] = useState();
const { data: ws, error, isLoading: wsLoading } = useGetWebSocketDataQuery();
useEffect(() => {
if (ws) {
ws?.positions?.map((i) => {
setPosition([i]);
console.log(i);
});
}
}, [ws]);
Icon.Default.mergeOptions({
iconUrl: "https://freesvg.org/img/car_topview.png",
iconSize: [32, 32], // size of the icon
shadowAnchor: [4, 62], // the same for the shadow
popupAnchor: [-3, -20], // point from which the popup should open relative to the iconAnchor
});
return (
<>
<MarkerClusterGroup chunkedLoading>
{position?.map((mark) => (
<Marker key={mark.id} position={[mark.latitude, mark.longitude]}>
<Popup closeOnEscapeKey>
<PositionsPopups mark={mark} />
</Popup>
</Marker>
))}
</MarkerClusterGroup>
</>
);
}
持仓代码弹出组件
import React, { useEffect, useState } from "react";
import PositionsPopupsDetails from "./PositionsPopupsDetails";
export default function PositionsPopups({ mark }) {
const [popupData, setPopupData] = useState(mark);
useEffect(() => {
setPopupData(mark);
}, [mark]);
return (
<>
<div className="device-popup">
{" "}
<PositionsPopupsDetails title="fix time" item={popupData.fixTime} />
<PositionsPopupsDetails
title="speed"
item={popupData.speed.toFixed(2) + ` KM`}
/>
<PositionsPopupsDetails title="address" item={popupData.address} />
<PositionsPopupsDetails
title="total distance"
item={Math.round(popupData.attributes.totalDistance / 1000) + ` KM`}
/>
</div>
</>
);
}
我尝试仅重新渲染弹出窗口中的数据,而不是整个弹出组件
position={[mark.latitude, mark.longitude]
组件上的 Marker
会强制其每次重新渲染,即使 mark.id
、mark.latitude
和 mark.longitude
相同。当 Marker
重新渲染时,Popup
也被强制重新渲染。这是因为您使用 []
创建了一个新的数组引用,这意味着即使数组中的值相同,道具也永远不会相等。创建一个可以 useMemo
该值的新组件,或者将纬度和经度作为它们自己的 props 传递。