React
Важно
Поддерживаемая версия React JS: не ниже 16.
JS API поддерживает интеграцию только с React JS.
На данный момент поддержки React Native нет.
Для каждого императивного класса API, который наследуется от YMapEntity, есть React-аналог. Чтобы воспользоваться React-версией API, подключите модуль @yandex/ymaps3-reactify:
const ymaps3Reactify = await ymaps3.import('@yandex/ymaps3-reactify');
const reactify = ymaps3Reactify.reactify.bindTo(React, ReactDOM);
const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapMarker} = reactify.module(ymaps3);
Модуль @yandex/ymaps3-reactify предоставляет набор методов для обращения в React как отдельных объектов, так и модулей/пакетов целиком. Иерархия объектов и параметры инициализации для большинства классов те же самые.
Подключив модуль, используйте объекты-наследники YMapEntity как React-компоненты:
<YMap location={{center: [37.588144, 55.733842], zoom: 9}} mode="vector">
<YMapDefaultSchemeLayer />
<YMapDefaultFeaturesLayer />
<YMapMarker coordinates={[37.588144, 55.733842]} draggable={true}>
<section>
<h1>You can drag this header</h1>
</section>
</YMapMarker>
</YMap>
Быстрый старт
Подключение через top-level-await
<!DOCTYPE html>
<html>
<head>
<!-- Вместо YOUR_API_KEY подставить значение настоящего ключа -->
<script src="https://api-maps.yandex.ru/v3/?apikey=YOUR_API_KEY&lang=ru_RU"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(<App />);
import {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapMarker, reactify} from './lib/ymaps3';
import type {YMapLocationRequest} from 'ymaps3';
const LOCATION: YMapLocationRequest = {
center: [37.588144, 55.733842],
zoom: 9
};
export default function App() {
return (
<div style={{width: '600px', height: '400px'}}>
<YMap location={reactify.useDefault(LOCATION)}>
<YMapDefaultSchemeLayer />
<YMapDefaultFeaturesLayer />
<YMapMarker coordinates={reactify.useDefault([37.588144, 55.733842])} draggable={true}>
<section>
<h1>You can drag this header</h1>
</section>
</YMapMarker>
</YMap>
</div>
);
}
import React from 'react';
import ReactDom from 'react-dom';
const [ymaps3React] = await Promise.all([ymaps3.import('@yandex/ymaps3-reactify'), ymaps3.ready]);
export const reactify = ymaps3React.reactify.bindTo(React, ReactDom);
export const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapMarker} = reactify.module(ymaps3);
{
"compilerOptions": {
"target": "es2017",
"lib": ["dom", "dom.iterable", "esnext"],
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"jsx": "react-jsx",
"typeRoots": ["./node_modules/@types", "./node_modules/@yandex/ymaps3-types"],
"paths": {
"ymaps3": ["./node_modules/@yandex/ymaps3-types"]
}
}
}
{
"devDependencies": {
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@yandex/ymaps3-types": "^0.0.27",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
"typescript": "^4.9.5"
},
"scripts": {
"start": "react-scripts start"
}
}
Поставьте зависимости и запустите локальный сервер:
npm install
npm start
Откройте приложение
Особенности
-
В
package.jsonдобавляем dev-зависимость от пакета@yandex/ymaps3-types.Рекомендуется устанавливать последнюю версию:
npm i --save-dev @yandex/ymaps3-types@latest -
В
tsconfig.jsonзадаёмcompilerOptions.typeRootsсо списком путей к файлам типов. Добавляем туда путь к пакету@yandex/ymaps3-types, благодаря чему в глобальной области видимости появляется пространство именymaps3с типами.Примечание
Пространство имен
ymaps3содержит все типы классов, которые предоставляет JS API, но до резолваymaps3.readyв среде выполнения они недоступны. -
В
tsconfig.jsonзадаёмcompilerOptions.paths, в которой сообщаем ts-компилятору о том, что при импорте пакетаymaps3его контент следует искать по указанному пути. Благодаря этому в проектных файлах можно импортировать типы словно они лежат не в@yandex/ymaps3-types, а в пакетеymaps3:import type {YMapLocationRequest} from 'ymaps3';Все типы должны быть импортированы из корня.
Внутренняя структура не гарантирована и может меняться со временем.
-
В
tsconfig.json, для корректной работы top-level-await, параметрcompilerOptions.moduleдолжен быть установлен в одно из следующих значений:es2022,esnext,systemилиpreserve. Также параметрcompilerOptions.targetдолжен бытьes2017или выше. -
Подключите модуль
@yandex/ymaps3-reactify. В файлеlib/ymaps3.tsдожидаемся полной загрузки JS API и reactify модуля, после чего экспортируем необходимые компоненты карты для их использования в других частях проекта:import React from 'react'; import ReactDom from 'react-dom'; const [ymaps3React] = await Promise.all([ymaps3.import('@yandex/ymaps3-reactify'), ymaps3.ready]); export const reactify = ymaps3React.reactify.bindTo(React, ReactDom); export const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer} = reactify.module(ymaps3);Примечание
Модуль
@yandex/ymaps3-reactifyпредоставляет набор методов для доступа к React как к отдельным объектам, так и к модулям/пакетам в целом. Иерархия объектов и параметры инициализации одинаковы. -
Использование top-level-await в
lib/ymaps3.tsгарантирует выполнениеymaps3.readyиymaps3.import('@yandex/ymaps3-reactify')до импорта компонентов карты, что позволяет синхронно использовать любые объекты JS API в качестве компонентов React:<YMap location={reactify.useDefault(LOCATION)}> <YMapDefaultSchemeLayer /> <YMapDefaultFeaturesLayer /> ... </YMap>
reactify.useDefault
YMap и все остальные компоненты – неконтролируемые. Компоненты используют императивный интерфейс библиотеки (например, YMapZoomControl вызывает YMap.update({location})). Это может вызывать рассинхронизацию с состоянием и параметрами в React (например location у YMap или coordinates у YMapMarker с включенным перетаскиванием).
Используйте reactify.useDefault(value), чтобы задать параметр компонента только один раз и не обновлять его при ререндерах. Например, <YMap location={reactify.useDefault({center, zoom})}/> будет вести себя как <input defaultValue={''}/>.
Чтобы контролировать обновление параметров, используйте второй параметр reactify.useDefault(value, deps) – массив зависимостей как в React hook'ах (например, useCallback, useMemo, useEffect). Параметр обновится, если массив зависимостей будет отличаться.
Для параметров с объектами, само значение может быть использовано как зависимость. Ререндер произойдет только, если значения будут отличаются. Например const [location, setLocation] = useState(...), reactify.useDefault(location, [location]), setLocation({...}).
reactify.useDefault работает с любыми параметрами любых компонентов из reactify.
Важно
reactify.useDefault возвращает объект без публичного контракта и должен быть использован только напрямую в параметрах компонентов.
Пользовательские реализации объектов ymaps3.YMapEntity для React
Используйте ymaps3.overrideKeyReactify ключ, чтобы определить пользовательскую реализацию объектов ymaps3.YMapEntity для reactify:
type YMapSomeClassProps = {
id: string;
};
export class YMapSomeClass extends ymaps3.YMapComplexEntity<YMapSomeClassProps> {
static [ymaps3.overrideKeyReactify] = YMapSomeClassReactifyOverride;
//...
}
и метод для определения пользовательской реализации:
export const YMapSomeClassReactifyOverride = (
YMapSomeClassI, // базовый класс YMapSomeClass
{reactify, React}
) => {
const YMapSomeClassReactified = reactify.entity(YMapSomeClassI); // Стандартный reactify метод
const YMapSomeClassR = React.forwardRef((props, ref) => {
return (<>
<YMapSomeClassReactified {...props} ref={ref} ... />
</>);
})
return YMapSomeClassR;
}
и добавим полученный компонент в приложение:
import {YMapSomeClass} from './some-class';
import React from 'react';
import ReactDOM from 'react-dom';
// ...
const ymaps3Reactify = await ymaps3.import('@yandex/ymaps3-reactify');
const reactify = ymaps3Reactify.reactify.bindTo(React, ReactDOM);
const YMapSomeClassR = reactify.entity(YMapSomeClass);
function App() {
return <YMapSomeClassR id="some_id" />;
}
Это библиотека JavaScript с открытым исходным кодом, которая используется для создания пользовательских интерфейсов для приложений.
Это JavaScript-фреймворк с открытым исходным кодом, появившийся после React JS, используется для разработки мобильных и веб-приложений.