Я использую API JavaScript Карт Google для своего веб-сайта вместе со службой автозаполнения мест. Проблема в том, что компонент автозаполнения не предлагает никаких местоположений, когда он помещен внутри Shadcn Accordion. Вот минимальный воспроизводимый пример, демонстрирующий эту проблему:
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../components/ui/accordion"
import { Input } from "../components/ui/input";
import { useEffect, useRef } from "react";
export default function AccountSettings() {
const autoCompleteRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (!autoCompleteRef.current) return;
new google.maps.places.Autocomplete(autoCompleteRef.current);
}, []);
return (
<div>
<Accordion type = "single" collapsible>
<AccordionItem value = "item-1">
<AccordionTrigger>
<span>Location Accordion</span>
</AccordionTrigger>
<AccordionContent>
<Input ref = {autoCompleteRef} placeholder = "Choose a location" />
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
)
}
Использование клавиш со стрелками и нажатие Enter ничего не дает, указывая на то, что предложения автозаполнения вообще не существуют. Если я удалю «Аккордеон» и помещу компонент «Ввод» на главную страницу, предложения автозаполнения будут отображаться правильно.
В консоли JavaScript нет ошибок, указывающих на то, что что-то не так. Я заметил одну вещь: если я открою Accordion, внесу изменения в свой код, а затем вернусь к экземпляру разработки, компонент автозаполнения предложит местоположения, что является правильным поведением. Я пытался отслеживать открытое состояние аккордеона, а затем условно отображать ввод автозаполнения с помощью isAccordionOpen &&
, но это ничего не дало.
Как я могу заставить компонент Google Autocomplete предлагать местоположения, когда он находится внутри Shadcn Accordion?
@MrUpsidown Я понимаю, что мой вопрос был плохо написан - я отредактировал вопрос, включив в него более подробное описание проблемы, а также мои усилия по отладке.
Я не работаю с React, но что произойдет, если вы разместите два компонента автозаполнения на одной странице без аккордеона? Они оба работают?
@MrUpsidown Да, если вы разместите два компонента автозаполнения на одной странице без аккордеона, они оба будут работать правильно. Я упростил свой пример, включив только один компонент автозаполнения.
Нашел ответ. Оказывается, вам нужно использовать forceMount
, чтобы сделать ввод автозаполнения независимым от открытого состояния аккордеона. Это гарантирует, что содержимое Accordion отображается в DOM независимо от открытого состояния. Затем используйте CSS, чтобы скрыть ввод, когда аккордеон не открыт.
Вот предоставленный пример с обновленным кодом:
export default function AccountSettings() {
// Keep track of open state
const [isAccordionExpanded, setIsAccordionExpanded] = useState("");
const autoCompleteRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (!autoCompleteRef.current) return;
new google.maps.places.Autocomplete(autoCompleteRef.current);
}, []);
return (
<div>
<Accordion type = "single"
collapsible
onValueChange = {setIsAccordionExpanded}
value = {isAccordionExpanded}>
<AccordionItem value = "item-1">
<AccordionTrigger>
<span>Location Accordion</span>
</AccordionTrigger>
{/* Use forceMount here and then hide the content when the accordion is closed */}
<AccordionContent forceMount className = {`${isAccordionExpanded ? 'block' : 'hidden'}`}>
<Input ref = {autoCompleteRef} placeholder = "Choose a location" />
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
);
}
Для этого примера я использовал TailwindCSS, но вы также можете использовать обычный CSS для того же эффекта скрытия, используя display: none
и display: block
до сих пор все работало нормально, и не работает, нет правильного описания проблемы. Что вы пытались отладить? Что говорит ваша консоль Javascript? и т. д.