问题描述
我要停止传播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>
</>
);
}