In Next.js I wrote a functionality that opens the balloon when you click on a marker on the yandex map using the React-yandex-maps library. The problem is that at the first click, the balloon opens and all the elements in it are displayed. Then I click on the cross at the top right of the balloon and on the next clicks the balloon opens, but the elements inside are not displayed:
Here is the code that I use to display the balloon, it is taken from here: Article
import { useEffect } from "react";
import { createPortal } from "react-dom";
export default function Portal({ children, getHTMLElementId }) {
// находим искомый HTML по id
const mount = document.getElementById(getHTMLElementId);
// создаём свой div
const el = document.createElement("div");
useEffect(() => {
// добавляем свой див к искомому элементу
if (mount) {
mount.appendChild(el);
}
return () => {
// удаляем элемент от искомого при завершении компоненты
if (mount) mount.removeChild(el);
};
}, [el, mount]);
// отменяем отрисовку при отсутствии искомого элемента
if (!mount) return null;
// собственно, пририсовываем React-элемент в div к искомому HTML
return createPortal(children, el);
}
Code for displaying everything on the map:
const DynamicPortalWithNoSSR = dynamic(() => import("./Portal"), {
ssr: false,
});
function WhMap({ posts, regionPosition, noRegionFlag }) {
const [activePortal, setActivePortal] = useState(false);
const [postPopup, setPostPopup] = useState(null);
const map = useRef();
return (
<div>
<YMaps>
<Map
id="map"
width="100%"
height="88vh"
defaultState={{ center: [59.9386, 30.3141], zoom: 13 }}
// включаем модули, отвечающие за всплывающие окна над геообъектами
modules={["geoObject.addon.balloon", "geoObject.addon.hint"]}
instanceRef={map}
>
{posts?.map((post) => (
<>
<Placemark
geometry={[
Number(post.latitude),
Number(post.longitude),
]}
options={{
preset: "islands#darkBlueCircleDotIcon",
iconColor: "#284AC2",
}}
properties={{
iconContent: "2", // пару символов помещается
// создаём пустой элемент с заданными размерами
balloonContent:
'<div id="driver-2" class="driver-card"></div>',
}}
onClick={() => {
requestAnimationFrame(() => {
setActivePortal(true);
setPostPopup(post);
});
}}
/>
</>
))}
</Map>
{activePortal && (
<DynamicPortalWithNoSSR getHTMLElementId="driver-2">
// здесь контент который отображается внутри balloon
</DynamicPortalWithNoSSR>
)}
</YMaps>
</Box>
);
}
export default WhMap;
