Skip to main content

Usage with React

You can use MapGL JS API in your React projects. Pay attention to the following instructions:

Note

You can start from the sample React project.


Preventing rerendering

Let's consider a basic React app:

import React from 'react';
import ReactDOM from 'react-dom';

import { App } from './App';

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

With a basic App component:

import React from 'react';

export const App = () => {
return <div>My App</div>;
};

To add a map to this app, we will create a component similar to this:

import { load } from '@2gis/mapgl';

export const Map = () => {
useEffect(() => {
let map;
load().then((mapglAPI) => {
map = new mapglAPI.Map('map-container', {
center: [55.31878, 25.23584],
zoom: 13,
key: 'Your API access key',
});
});

// Destroy the map on unmount
return () => map && map.destroy();
}, []);

return (
<div style={{ width: '100%', height: '100%' }}>
<MapWrapper />
</div>
);
};

Notice that this component does not include the container for the map (map-container). To prevent the rerendering of the map, we will create a separate component and use React.memo to skip the rendering:

const MapWrapper = React.memo(
() => {
return <div id="map-container" style={{ width: '100%', height: '100%' }}></div>;
},
() => true,
);

The second argument is a function that determines if the last rendered result should be used instead of rendering the component again. In our case, it will always return true.

Finally, we will update the App component and everything should be ready to go:

export const App = () => {
return (
<div style={{ width: '100%', height: 400 }}>
<Map />
</div>
);
};

You can find the full source code in the example below.

Accessing the map

The second difficulty is accessing the map component from another component.

Let's say, for example, that we want to make a button that will change the center of the map. This button will be in a separate component, so we need to access the map component from the button component. We can use the React Context API to do this.

First, let's create a new component and call React.createContext() to create a Context object:

const MapContext = React.createContext([undefined, () => {}]);
const MapProvider = (props) => {
const [mapInstance, setMapInstance] = React.useState();

return (
<MapContext.Provider value={[mapInstance, setMapInstance]}>
{props.children}
</MapContext.Provider>
);
};

Then we will wrap the App component with MapProvider. This way, the new context will be available to the App component and all its children components.

ReactDOM.render(
<MapProvider>
<App />
</MapProvider>,
rootElement,
);

Now that we have a context, we can use it to store the map instance. We will do that in our Map component:

export const Map = () => {
const [_, setMapInstance] = React.useContext(MapContext);

useEffect(() => {
let map;
load().then((mapglAPI) => {
map = new mapglAPI.Map('map-container', {
center: [55.31878, 25.23584],
zoom: 13,
key: 'Your API access key',
});

// Store map instance
setMapInstance(map);
});

// Destroy the map on unmount
return () => map && map.destroy();
}, []);

return (
<div style={{ width: '100%', height: '100%' }}>
<MapWrapper />
</div>
);
};

Finally, we will create a component that will use the stored map instance to recenter the map:

export const MoveMapButton = () => {
const [mapInstance] = React.useContext(MapContext);

const setInitialCenter = useCallback(() => {
if (mapInstance) {
mapInstance.setCenter([55.31878, 25.23584]);
}
}, [mapInstance]);

return <button onClick={setInitialCenter}>Set initial center</button>;
};

You can find the full source code in the example below.

Ready-to-use npm package

If you are using npm, take a look at the @2gis/mapgl package, which also includes TypeScript support.

You can find examples and more information in the Readme.

Example of using in side projects

The example of using MapGL in a side project you can find in github.com/city-mobil/frontend_react-2gis repository with a React wrapper implementation. Also there is a npm package of this wrapper - react-2gis.