最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React-Leaflet Map doesn't update - Stack Overflow

programmeradmin0浏览0评论

My issue is that react-leaflet <MapContainer> doesn't center on a position that I set dynamically. The basic logic is that I have a form where I enter Street and House Number, then I make call for Nominatim and get some JSON format data, from where I extract latitude and longitude of a building. These lat and long I pass to my <MapContainer> but it doesn't respond anyhow. With react-leaflet v2 with it was working pretty good, but after I updated to v3 it stopped.

Whenever I set default position values MapContainer centers on that position. But when I pass another value dynamically through Nominatim call it doesn't work.

Here I make call for Nominatim:

const getSearchData = async () => {
    const exampleReq = `/${query}?format=json&building=*&addressdetails=1&limit=1&polygon_geojson=1`;
    const response = await fetch(exampleReq);
    const data = await response.json();
    // console.log(data);
    if (data === undefined || data.length === 0) {
        // array empty or does not exist
        console.log("data array is empty");
        alert("Given address unrecognized! Try again please.")
        setLatitude(DEFAULT_LATITUDE);
        setLongitude(DEFAULT_LONGITUDE);
    }else{
        setLatitude(data[0].lat);
        setLongitude(data[0].lon);
    }
};

This is onSubmit of my form:

<form className={style.searchForm} onSubmit={e => {
                e.preventDefault();
                setQuery(street + " " + houseNumber.replace(/\//g, "-") + ", Tallinn");
                setPosition({
                    ltd: lat, 
                    lng: long
                });

And here is my MapBox ponent which contains my leaflet Map:

const MapBox = (props) => {

  useEffect(()=>{
      console.log("MAPBOX!");
      console.log("updateMap() - lat ---> " + props.latitude);
      console.log("updateMap() - long ---> " + props.longitude);
      updateMap();
  },[props.street, props.houseNumber]);

  const passStreet = props.street;
  const passHouseNumber = props.houseNumber;

  const updateMap = () => {
    // console.log("updateMap() - lat ---> " + props.latitude);
    // console.log("updateMap() - long ---> " + props.longitude);
    return(
        <MapContainer center={[props.latitude, props.longitude]} zoom={20}>
            <TileLayer
                url='https://{s}.tile.osm/{z}/{x}/{y}.png'
                attribution='&copy; <a href=";>OpenStreetMap</a> contributors'
            />
            <OverpassLayer street={passStreet} houseNumber={passHouseNumber} />
        </MapContainer>
      );
  }

  return(
    updateMap()
  );
}

My issue is that react-leaflet <MapContainer> doesn't center on a position that I set dynamically. The basic logic is that I have a form where I enter Street and House Number, then I make call for Nominatim and get some JSON format data, from where I extract latitude and longitude of a building. These lat and long I pass to my <MapContainer> but it doesn't respond anyhow. With react-leaflet v2 with it was working pretty good, but after I updated to v3 it stopped.

Whenever I set default position values MapContainer centers on that position. But when I pass another value dynamically through Nominatim call it doesn't work.

Here I make call for Nominatim:

const getSearchData = async () => {
    const exampleReq = `https://nominatim.openstreetmap/search/${query}?format=json&building=*&addressdetails=1&limit=1&polygon_geojson=1`;
    const response = await fetch(exampleReq);
    const data = await response.json();
    // console.log(data);
    if (data === undefined || data.length === 0) {
        // array empty or does not exist
        console.log("data array is empty");
        alert("Given address unrecognized! Try again please.")
        setLatitude(DEFAULT_LATITUDE);
        setLongitude(DEFAULT_LONGITUDE);
    }else{
        setLatitude(data[0].lat);
        setLongitude(data[0].lon);
    }
};

This is onSubmit of my form:

<form className={style.searchForm} onSubmit={e => {
                e.preventDefault();
                setQuery(street + " " + houseNumber.replace(/\//g, "-") + ", Tallinn");
                setPosition({
                    ltd: lat, 
                    lng: long
                });

And here is my MapBox ponent which contains my leaflet Map:

const MapBox = (props) => {

  useEffect(()=>{
      console.log("MAPBOX!");
      console.log("updateMap() - lat ---> " + props.latitude);
      console.log("updateMap() - long ---> " + props.longitude);
      updateMap();
  },[props.street, props.houseNumber]);

  const passStreet = props.street;
  const passHouseNumber = props.houseNumber;

  const updateMap = () => {
    // console.log("updateMap() - lat ---> " + props.latitude);
    // console.log("updateMap() - long ---> " + props.longitude);
    return(
        <MapContainer center={[props.latitude, props.longitude]} zoom={20}>
            <TileLayer
                url='https://{s}.tile.osm/{z}/{x}/{y}.png'
                attribution='&copy; <a href="http://osm/copyright">OpenStreetMap</a> contributors'
            />
            <OverpassLayer street={passStreet} houseNumber={passHouseNumber} />
        </MapContainer>
      );
  }

  return(
    updateMap()
  );
}
Share Improve this question edited Nov 8, 2020 at 10:36 Striped 2,5473 gold badges27 silver badges33 bronze badges asked Nov 8, 2020 at 9:59 ArmanKArmanK 1551 silver badge9 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 11

I was able to solve it. In documentation it is stated as:

Except for its children, MapContainer props are immutable: changing them after they have been set a first time will have no effect on the Map instance or its container. The Leaflet Map instance created by the MapContainer element can be accessed by child ponents using one of the provided hooks or the MapConsumer ponent.

This piece of code helps to understand:

function MyComponent() {
  const map = useMap()
  console.log('map center:', map.getCenter())
  return null
}

function MyMapComponent() {
  return (
    <MapContainer center={[50.5, 30.5]} zoom={13}>
      <MyComponent />
    </MapContainer>
  )
}

What I implemented:

function MyComponent(props) {
const map = useMap();
map.setView(props.center, props.zoom);
return null;
}
发布评论

评论列表(0)

  1. 暂无评论