Link 列表中的结果项到地图传单上的标记

Link the result items from a list to the marker on map leaflet

我正在尝试 link 带有传单地图的列表。我想单击结果卡并查看地图上的标记。我现在使用 json 格式的假数据。我想要一个类似airbnb的显示,list plus display the list on map.

这是地图文件:

import React, { useState } from "react";
import { Map, TileLayer, Marker, Popup } from "react-leaflet";
import "leaflet/dist/leaflet.css";
import { Icon } from "leaflet";
import FakeData from "../../../../../../data";
import {Div, PopContainer} from "./style"



const MarkerIcon = new Icon({
  iconUrl: "../public/markerIcon.png",
  iconSize: [50, 50],
});

function MapBox() {
  const [nurse, setNurse] = useState(null);
  const bull = <span>•</span>;

  return (
    <Div>
      <Map center={[50.6365654, 3.0635282]} zoom={13} scrollWheelZoom={false}>
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png"
        />
        {FakeData.map((data) => (
          <Marker
            key={data.id}
            icon={MarkerIcon}
            position={[data.coordonatelat, data.coordonatelng]}
            onmouseover={() => {
              setNurse(data);
            }}
          />
        ))}
        {nurse && (
          <Popup
            position={[nurse.coordonatelat, nurse.coordonatelng]}
            onClose={() => {
              setNurse(null);
            }}
          >
            <PopContainer>
              <h2>
                {bull}
                {nurse.first_name} {nurse.last_name}
                {bull}
              </h2>
              <h3>
                {nurse.job}
               </h3> 
               <p> {nurse.address}
                <br />
                {nurse.phone_number}
              </p>
            </PopContainer>
          </Popup>
        )}
      </Map>
    </Div>
  );
}

export default MapBox;

这是结果页面:

import React from "react";
import FakeData from "../../../../../../data";
import MapBox from "../map/index";
import { Scrollbars } from "react-custom-scrollbars";
import {
  Container,
  H1,
  Card,
  CardContent,
  H2,
  Address,
  Phone,
  NavLink,
  CardActions,
  Job,
  MapContainer,
  BigContainer,
  CardContainer,
  Box,
  Li,
} from "./resultPageStyle";

function Result(props) {
  const bull = <span>•</span>;

  return (
    <BigContainer>
      <Container>
        <H1>Résultats</H1>
        <Box>
          <Scrollbars style={{ width: 650, height: 580 }}>
            <CardContainer>
              {FakeData.slice(0, 30).map((item) => (
                <Li key={item.id}>
                  <Card>
                    <CardContent>
                      <Job>{item.job}</Job>
                      <H2>
                        {bull}
                        {item.first_name} {item.last_name}
                        {bull}
                      </H2>
                      <Address>{item.address}</Address>
                      <Phone>{item.phone_number}</Phone>
                    </CardContent>
                    <CardActions>
                      <NavLink to={"/detailsPage"}>Plus d'infos</NavLink>
                    </CardActions>
                  </Card>
                </Li>
              ))}
            </CardContainer>
          </Scrollbars>

          <MapContainer>
            <MapBox />
          </MapContainer>
        </Box>
      </Container>
    </BigContainer>
  );
}

export default Result;

我尝试了不同的方法,但它不起作用。

  1. Result comp 上创建一个状态变量以跟踪包含 lat lng 信息的卡片项目
  2. 将其作为道具传递给 Mapbox comp
  3. Mapbox comp 上创建一个局部变量来保存地图实例,并在每次单击卡片时使用它来更改地图视图。

分频器

function Result() {
      const bull = <span>•</span>;
      const [cardItem, setCardItem] = useState(null);
    
      const handleCardClick = (item) => {
        console.log(item);
        setCardItem(item);
      };
      ...
      <Card onClick={() => handleCardClick(item)}>
      ...
      <MapContainer>
        <MapBox cardItem={cardItem} />
      </MapContainer>
}

分频器

 function MapBox({ cardItem }) {
      const [nurse, setNurse] = useState(null);
      const bull = <span>•</span>;
      const [map, setMap] = useState(null);
    
      useEffect(() => {
        if (!cardItem || !map) return;
        const { coordonatelat, coordonatelng } = cardItem;
        map.setView([coordonatelat, coordonatelng], 13);
      }, [cardItem, map]);
      ...
 }

我还修复了您的演示问题,并在您将鼠标悬停在每张卡片上时添加了一个光标。

您也可以使用 map.flyTo,它提供开箱即用的漂亮动画,而不是 map.setView。由你决定。

Demo