StopPropagation反应Google Maps自动完成

问题描述

我要停止传播https://react-google-maps-api-docs.netlify.app/#autocomplete自动完成效果很好,但是我需要在弹出窗口中使用它,当我选择一个位置时,弹出窗口会自动关闭

如果还有另一个可以很好地处理弹出窗口和模式的库

const [autocomplete,setAutocomplete] = useState<any>(null);
        const onLoad = (auto: any) => {
            if (!autocomplete) {
                setAutocomplete(auto);
            }

        };

        const onPlaceChanged = () => {
            if (autocomplete) {

                console.log(autocomplete?.getPlace());

            } else {
                console.log('Autocomplete is not loaded yet!');
            }
        };

<Autocomplete
                            onLoad={onLoad}
                            onPlaceChanged={onPlaceChanged}
                        >

                            <chakra.input
                                type='text'
                                as={Input}
                                placeholder='Customized your placeholder'
                                style={{
                                    BoxSizing: `border-Box`,border: `1px solid transparent`,width: `240px`,height: `32px`,padding: `0 12px`,borderRadius: `3px`,BoxShadow: `0 2px 6px rgba(0,0.3)`,fontSize: `14px`,outline: `none`,textOverflow: `ellipses`,position: 'absolute',left: '50%',marginLeft: '-120px',animationName: 'none',zIndex: 9999,}}
                            />
                        </Autocomplete>

解决方法

我正在使用chakraUI,我从discord(dodas用户)那里得到了帮助,这是他的解决方案。基本上,他捕获了mousedown事件(Google阻止点击事件),并且当弹出窗口打开时,选择项目或单击触发按钮对其他事件不执行任何操作,只是关闭弹出窗口。

https://codesandbox.io/s/popovergoogle-autocomplete-6nvtb?file=/src/App.js:0-3329

import React,{ useState,useEffect,useRef } from "react";
import {
  Button,Stack,Popover,PopoverTrigger,PopoverContent,PopoverHeader,PopoverBody,PopoverArrow,PopoverCloseButton,Box,Portal,PopoverFooter,useRadioGroup,useRadio
} from "@chakra-ui/core";
import { useEvent } from "react-use";
import {
  GoogleMap,useJsApiLoader,Autocomplete
} from "@react-google-maps/api";

let autoComplete;

export function App() {
  const { isLoaded,loadError } = useJsApiLoader({
    googleMapsApiKey: "YOUR_KEY",//,libraries: ["places"]
    // ...otherOptions
  });

  const [isPopoverOpen,setIsPopoverOpen] = useState(false);
  const openPopover = () => setIsPopoverOpen(true);
  const closePopover = () => setIsPopoverOpen(false);

  const triggerRef = useRef(null);
  const popoverContentRef = useRef(null);
  const [autocomplete,setAutocomplete] = useState(null);

  const onLoad = (autocompleteInstance) => {
    console.log("autocomplete: ",autocomplete);
    setAutocomplete(autocompleteInstance);
  };

  const onPlaceChanged = () => {
    if (autocomplete) {
      console.log(autocomplete.getPlace());
    } else {
      console.log("Autocomplete is not loaded yet!");
    }
  };

  useEvent("mousedown",(ev) => {
    if (!isPopoverOpen) {
      return;
    }

    const clickedInsideTrigger = triggerRef.current.contains(ev.target);

    const clickedInsidePopover = popoverContentRef.current.contains(ev.target);

    const clickedInsideAutocomplete =
      ev.target.closest(".pac-container") != null;

    if (
      clickedInsideTrigger ||
      clickedInsidePopover ||
      clickedInsideAutocomplete
    ) {
      return;
    }

    closePopover();
  });

  return (
    <>
      <Box width="100vw" height="100vh">
        <Popover
          isOpen={isPopoverOpen}
          onOpen={openPopover}
          onClose={closePopover}
          closeOnBlur={false}
          isLazy
          placement="bottom-end"
        >
          <PopoverTrigger>
            <Button ref={triggerRef}>Trigger</Button>
          </PopoverTrigger>

          <PopoverContent ref={popoverContentRef}>
            <PopoverArrow />
            <PopoverCloseButton />
            <PopoverHeader>Confirmation!</PopoverHeader>
            <PopoverBody minH="20rem">
              {isLoaded && (
                <Autocomplete onLoad={onLoad} onPlaceChanged={onPlaceChanged}>
                  <input
                    type="text"
                    placeholder="Customized your placeholder"
                    style={{
                      boxSizing: `border-box`,border: `1px solid transparent`,width: `240px`,height: `32px`,padding: `0 12px`,borderRadius: `3px`,boxShadow: `0 2px 6px rgba(0,0.3)`,fontSize: `14px`,outline: `none`,textOverflow: `ellipses`,position: "absolute",left: "50%",marginLeft: "-120px"
                    }}
                  />
                </Autocomplete>
              )}
            </PopoverBody>
          </PopoverContent>
        </Popover>
      </Box>
    </>
  );
}