0

I have a component that autocompletes places on my page that manages To and From destinations. Within the component, there are additional utilities, for example returning the geocoding of the given position.

How can I pass back the geocoded data back to the page? Anybody has any idea on best practice patterns to do this?

Example component: PlacesAutocomplete.jsx from https://github.com/wellyshen/use-places-autocomplete#create-the-component

import usePlacesAutocomplete, {
  getGeocode,
  getLatLng,
} from "use-places-autocomplete";
import useOnclickOutside from "react-cool-onclickoutside";

const PlacesAutocomplete = () => {
  const {
    ready,
    value,
    suggestions: { status, data },
    setValue,
    clearSuggestions,
  } = usePlacesAutocomplete({
    callbackName: "YOUR_CALLBACK_NAME",
    requestOptions: {
      /* Define search scope here */
    },
    debounce: 300,
  });
  const ref = useOnclickOutside(() => {
    // When user clicks outside of the component, we can dismiss
    // the searched suggestions by calling this method
    clearSuggestions();
  });

  const handleInput = (e) => {
    // Update the keyword of the input element
    setValue(e.target.value);
  };

  const handleSelect =
    ({ description }) =>
    () => {
      // When user selects a place, we can replace the keyword without request data from API
      // by setting the second parameter to "false"
      setValue(description, false);
      clearSuggestions();

      // Get latitude and longitude via utility functions
      getGeocode({ address: description }).then((results) => {
        const { lat, lng } = getLatLng(results[0]);
        console.log(" Coordinates: ", { lat, lng });
      });
    };

  const renderSuggestions = () =>
    data.map((suggestion) => {
      const {
        place_id,
        structured_formatting: { main_text, secondary_text },
      } = suggestion;

      return (
        <li key={place_id} onClick={handleSelect(suggestion)}>
          <strong>{main_text}</strong> <small>{secondary_text}</small>
        </li>
      );
    });

  return (
    <div ref={ref}>
      <input
        value={value}
        onChange={handleInput}
        disabled={!ready}
        placeholder="Where are you going?"
      />
      {/* We can use the "status" to decide whether we should display the dropdown or not */}
      {status === "OK" && <ul>{renderSuggestions()}</ul>}
    </div>
  );
};

Example page: index.jsx

import { PlacesAutocomplete } from @/components/PlacesAutocomplete

export default function Example() {

  return (
    <div className="bg-white">
      <PlacesAutocomplete /> 
      <PlacesAutocomplete /> {/* I want to return the long and lat values here */}
    <div>
}

The component is used multiple times on the page. I have considered creating the input fields directly on the page but it seems counterintuitive that I will have to intialize the autocomplete input multiple times.

jmargolisvt
  • 5,722
  • 4
  • 29
  • 46
BernardL
  • 5,162
  • 7
  • 28
  • 47
  • After edits - now try to create a function in your page like `const onLatLngLoaded = (data) => console.log(data)` and try to pass this function to your child components like ``. Change `const PlacesAutocomplete = ({onLatLngLoaded})` and now just call this function with your data instead of console loggin it. Or If that is not what was needed - feel free to include more details and desired behavior in your question. – Sergey Sosunov Feb 12 '23 at 17:09
  • I think the most straight forward solution is to use a callback, like suggested above by Sergey. – Camilo Feb 12 '23 at 17:13
  • So in summary create a callback function on the page? – BernardL Feb 12 '23 at 17:17
  • Well probably, Im still not sure about what was your plan with this data, when it should be loaded, when and how should it be used, etc. Basically those are the only solutions, state lifting or a callback function. – Sergey Sosunov Feb 12 '23 at 17:20
  • Thanks, its getting somewhere. The plan is to get the geocodes passed to the page and then be submitted as part of the form on the page itself. At the moment callbacks seem to be working. Is it normal to use callbacks and then `setState` on each of them? – BernardL Feb 12 '23 at 17:34
  • Hard to tell without seeing the code, but it is normal to execute setState from inside those callback functions – Sergey Sosunov Feb 12 '23 at 17:41

0 Answers0