Skip to content

Instantly share code, notes, and snippets.

@ValeryVS
Created April 2, 2020 14:15
Show Gist options
  • Save ValeryVS/56324c6a43dbbd32fd1356e2dae4e7ac to your computer and use it in GitHub Desktop.
Save ValeryVS/56324c6a43dbbd32fd1356e2dae4e7ac to your computer and use it in GitHub Desktop.
vector-yandex-maps-react-typescript
import React from 'react';
// @ts-ignore
export const MapsContext = React.createContext<typeof ymaps | null>(null);
MapsContext.displayName = 'SDCYandexMaps';
export {SDCYandexMapsProvider} from './provider';
export {withYmaps} from './with-ymaps';
export {Map} from './map';
import React, {useEffect, useRef} from 'react';
import {withYmaps} from './with-ymaps';
interface MapProps {
className?: string;
}
export const Map: React.FC<MapProps> = withYmaps(({
className,
children,
ymaps,
}) => {
const mapRef = useRef<HTMLDivElement>(null);
const ymapsMapRef = useRef<ymaps.Map>();
useEffect(() => {
if (!ymaps) {
return;
}
ymaps.ready(() => {
if (!mapRef.current) {
throw new Error('No map container found');
}
ymapsMapRef.current = new window.ymaps.Map(mapRef.current, {
center: [55.753930, 37.621401],
zoom: 10.77,
}, {
// @ts-ignore
vector: true,
});
});
}, [ymaps]);
return (
<div
ref={mapRef}
className={className}
>
{children}
</div>
);
});
import React, {useEffect, useState} from 'react';
import {MapsContext} from './context';
const baseUrl = 'https://api-maps.yandex.ru';
const version = '2.1';
const queryParams = {
lang: 'ru_RU',
load: 'Map,vectorEngine.preload',
};
export const SDCYandexMapsProvider: React.FC = React.memo(({children}) => {
const [loadedYmaps, setLoadedYmaps] = useState(null);
useEffect(() => {
const script = document.createElement('script');
script.type = 'text/javascript';
script.onload = () => {
// @ts-ignore
setLoadedYmaps(window.ymaps);
};
const queryString = Object.entries(queryParams)
.map(([key, value]) => `${key}=${value}`)
.join('&');
script.src = `${baseUrl}/${version}?${queryString}`;
script.async = true;
document.head.appendChild(script);
}, []);
return (
<MapsContext.Provider value={loadedYmaps}>
{children}
</MapsContext.Provider>
);
});
import React from 'react';
import {MapsContext} from './context';
export interface WithYmapsProps {
ymaps: React.ContextType<typeof MapsContext>;
}
export const withYmaps = <P extends object>(
Component: React.ComponentClass<P & WithYmapsProps> | React.FC<P & WithYmapsProps>,
) => {
const WithYpamsContext: React.FC<P> = (props: P) => (
<MapsContext.Consumer>
{(ymaps) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<Component ymaps={ymaps} {...props} />
)}
</MapsContext.Consumer>
);
return WithYpamsContext;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment