渲染组件中的项目而不是整个组件

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

正在从 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>
    </>
  );
}

我尝试仅重新渲染弹出窗口中的数据,而不是整个弹出组件

javascript reactjs react-hooks websocket
1个回答
0
投票

position={[mark.latitude, mark.longitude]
组件上的
Marker
会强制其每次重新渲染,即使
mark.id
mark.latitude
mark.longitude
相同。当
Marker
重新渲染时,
Popup
也被强制重新渲染。这是因为您使用
[]
创建了一个新的数组引用,这意味着即使数组中的值相同,道具也永远不会相等。创建一个可以 useMemo 该值的新组件,或者将纬度和经度作为它们自己的 props 传递。
    

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