SamSamskies / react-map-gl-geocoder

React wrapper for mapbox-gl-geocoder for use with react-map-gl
MIT License
122 stars 29 forks source link

Dopdown is disappearing after searching the results in react-map-gl-geocoder #85

Closed Maruthasalam closed 3 years ago

Maruthasalam commented 4 years ago
issues

In React Map GL Gecoder Package after searching the items from input box, the results are shown in the dropdown and i select the items from the dropdwon list.the dropdwon list is hangs in there and disappering so how to over come the issues?Can please help out. Here is my code below <Geocoder mapRef={mapRef} onViewportChange={(e) => handleGeocoderViewportChange(e)} mapboxApiAccessToken={TOKEN} position="top-right" /> const handleViewportChange = useCallback((newviewport) => { setviewport(newviewport) },[]); const handleGeocoderViewportChange = useCallback((viewport) => { const geocoderDefaultOverrides = { transitionDuration: 1000 }; return handleViewportChange({ ...viewport, ...geocoderDefaultOverrides, }); },[handleViewportChange]);

SamSamskies commented 4 years ago

Hi @Maruthasalam. In order to avoid this, the value for onViewportChange needs to be memoized. In your example you are passing a new function to onViewportChange on every render which is causing the problem that you are having.

Try this:

<Geocoder
    mapRef={mapRef}
    onViewportChange={handleGeocoderViewportChange}
    mapboxApiAccessToken={TOKEN}
    position="top-right"
/>
utb2017 commented 4 years ago

I am having a similar problem. A). I only see one suggestion. B) The suggestion disappears when I click it. The map animates to the location. The Single suggestion then reappears.

I can get the suggestion to disappear if I focus the Input, then click away. If I move the map, the suggestion will reappear.

I am using nextJS, I overcame the "window is not defined", error.

I am using the container ref and the input is outside the box.

import { useState, useRef, forwardRef, useCallback } from 'react'
import ReactMapGL from 'react-map-gl'
import Geocoder from 'react-map-gl-geocoder'

const TOKEN = `foobar`

const Map = forwardRef(( props, ref) => {
  const state =  {
      width: '100%',
      height: '100%',
       latitude: 41.5868,
       longitude: -93.625,
      zoom: 13
  };
  const mapRef = useRef();
  const [view, setView] = useState(state);

  const handleViewportChange = useCallback((viewport) => {
    setView(viewport);
  });

    return (
      <ReactMapGL
        ref={mapRef}
        mapStyle="mapbox://styles/mapbox/streets-v9"
        mapboxApiAccessToken={TOKEN}
        onViewportChange={handleViewportChange}
        {...view}
      >
       <Geocoder
          mapRef={mapRef}
          onViewportChange={handleViewportChange}
          containerRef={ref}
          mapboxApiAccessToken={TOKEN}
          countries={'US'}
          proximity={{latitude:34.103729, longitude:-118.328613}}
          position="top-left"
        /> 

      </ReactMapGL>
    );
})

export default Map;
"react-map-gl": "^5.2.7",
"react-map-gl-geocoder": "^2.1.5",

Seems like a focus problem?

Link to Img Example

Link to Video Example

I also wrapped this component in a memo and nothing changes. I removed the forwardRef and containerRef also, still shows 1 suggestion and acts the same as described above.

UPDATE I increased the height of the suggestion box and found more results. The single result seems like a CSS conflict, but the suggestion still pop back up when the map finishes moving to a location.

Fixed css

body, html, legend, td, th, ul {
    padding: 0;
    /* height: 100%; */
}

This line was causing me to see 1 suggestion. It could also be avoided if height:unset was added to .mapboxgl-ctrl-geocoder .suggestions

.mapboxgl-ctrl-geocoder .suggestions {
    height: unset;
}
SamSamskies commented 4 years ago

Hi @utb2017, you're missing the deps on your useCallback. You actually don't need the useCallback in your case. And your proximity value needs to be memoized or defined outside of the function. The mapbox geocoder gets re-initialized every time a reference to a non-primitive value changes.

import { useState, useRef, forwardRef, useCallback } from 'react'
import ReactMapGL from 'react-map-gl'
import Geocoder from 'react-map-gl-geocoder'

const TOKEN = `foobar`
const PROXIMITY = {latitude:34.103729, longitude:-118.328613}

const Map = forwardRef(( props, ref) => {
  const state =  {
      width: '100%',
      height: '100%',
       latitude: 41.5868,
       longitude: -93.625,
      zoom: 13
  };
  const mapRef = useRef();
  const [view, setView] = useState(state);

    return (
      <ReactMapGL
        ref={mapRef}
        mapStyle="mapbox://styles/mapbox/streets-v9"
        mapboxApiAccessToken={TOKEN}
        onViewportChange={setView}
        {...view}
      >
       <Geocoder
          mapRef={mapRef}
          onViewportChange={setView}
          containerRef={ref}
          mapboxApiAccessToken={TOKEN}
          countries={'US'}
          proximity={PROXIMITY}
          position="top-left"
        /> 

      </ReactMapGL>
    );
})

export default Map;
utb2017 commented 4 years ago

@SamSamskies Thank you!!